1 <html><head><meta http-equiv=
"Content-Type" content=
"text/html; charset=ISO-8859-1"><title>SAMBA Developers Guide
</title><link rel=
"stylesheet" href=
"samba.css" type=
"text/css"><meta name=
"generator" content=
"DocBook XSL Stylesheets V1.60.1"><meta name=
"description" content=
"
2 Last Update : Fri Jun 6 00:45:54 CEST 2003
4 This book is a collection of documents that might be useful for
5 people developing samba or those interested in doing so.
6 It's nothing more than a collection of documents written by samba developers about
7 the internals of various parts of samba and the SMB protocol. It's still incomplete.
8 The most recent version of this document
9 can be found at http://devel.samba.org/.
10 Please send updates to Jelmer Vernooij.
12 This documentation is distributed under the GNU General Public License (GPL)
13 version 2. A copy of the license is included with the Samba source
14 distribution. A copy can be found on-line at http://www.fsf.org/licenses/gpl.txt
15 "></head><body bgcolor=
"white" text=
"black" link=
"#0000FF" vlink=
"#840084" alink=
"#0000FF"><div class=
"book" lang=
"en"><div class=
"titlepage"><div><div><h1 class=
"title"><a name=
"Samba-Developers-Guide"></a>SAMBA Developers Guide
</h1></div><div><div class=
"author"><h3 class=
"author"><span class=
"surname">SAMBA Team
</span></h3></div></div><div><div class=
"legalnotice"><p><b>Attributions.
</b>
16 </p><div class=
"variablelist"><dl><dt><span class=
"term"><a href=
"#netbios" title=
"Chapter 1. Definition of NetBIOS Protocol and Name Resolution Modes">Definition of NetBIOS Protocol and Name Resolution Modes
</a></span></dt><dd><div class=
"itemizedlist"><ul type=
"disc"><li><p>Luke Leighton
</p></li></ul></div></dd><dt><span class=
"term"><a href=
"#architecture" title=
"Chapter 2. Samba Architecture">Samba Architecture
</a></span></dt><dd><div class=
"itemizedlist"><ul type=
"disc"><li><p>Dan Shearer
</p></li></ul></div></dd><dt><span class=
"term"><a href=
"#debug" title=
"Chapter 3. The samba DEBUG system">The samba DEBUG system
</a></span></dt><dd><div class=
"itemizedlist"><ul type=
"disc"><li><p>Chris Hertel
</p></li></ul></div></dd><dt><span class=
"term"><a href=
"#CodingSuggestions" title=
"Chapter 4. Coding Suggestions">Coding Suggestions
</a></span></dt><dd><div class=
"itemizedlist"><ul type=
"disc"><li><p>Steve French
</p></li><li><p>Simo Sorce
</p></li><li><p>Andrew Bartlett
</p></li><li><p>Tim Potter
</p></li><li><p>Martin Pool
</p></li></ul></div></dd><dt><span class=
"term"><a href=
"#internals" title=
"Chapter 5. Samba Internals">Samba Internals
</a></span></dt><dd><div class=
"itemizedlist"><ul type=
"disc"><li><p>David Chappell
<<a href=
"mailto:David.Chappell@mail.trincoll.edu" target=
"_top">David.Chappell@mail.trincoll.edu
</a>></p></li></ul></div></dd><dt><span class=
"term"><a href=
"#parsing" title=
"Chapter 6. The smb.conf file">The smb.conf file
</a></span></dt><dd><div class=
"itemizedlist"><ul type=
"disc"><li><p>Chris Hertel
</p></li></ul></div></dd><dt><span class=
"term"><a href=
"#unix-smb" title=
"Chapter 7. NetBIOS in a Unix World">NetBIOS in a Unix World
</a></span></dt><dd><div class=
"itemizedlist"><ul type=
"disc"><li><p>Andrew Tridgell
</p></li></ul></div></dd><dt><span class=
"term"><a href=
"#tracing" title=
"Chapter 8. Tracing samba system calls">Tracing samba system calls
</a></span></dt><dd><div class=
"itemizedlist"><ul type=
"disc"><li><p>Andrew Tridgell
</p></li></ul></div></dd><dt><span class=
"term"><a href=
"#windows-debug" title=
"Chapter 9. Finding useful information on windows">Finding useful information on windows
</a></span></dt><dd><div class=
"itemizedlist"><ul type=
"disc"><li><p>Jelmer Vernooij
<<a href=
"mailto:jelmer@samba.org" target=
"_top">jelmer@samba.org
</a>></p></li><li><p>Andrew Tridgell
<<a href=
"mailto:tridge@samba.org" target=
"_top">tridge@samba.org
</a>></p></li></ul></div></dd><dt><span class=
"term"><a href=
"#ntdomain" title=
"Chapter 10. NT Domain RPC's">NT Domain RPC's
</a></span></dt><dd><div class=
"itemizedlist"><ul type=
"disc"><li><p>Luke Leighton
<<a href=
"mailto:lkcl@switchboard.net" target=
"_top">lkcl@switchboard.net
</a>></p></li><li><p>Paul Ashton
<<a href=
"mailto:paul@argo.demon.co.uk" target=
"_top">paul@argo.demon.co.uk
</a>></p></li><li><p>Duncan Stansfield
<<a href=
"mailto:duncans@sco.com" target=
"_top">duncans@sco.com
</a>></p></li></ul></div></dd><dt><span class=
"term"><a href=
"#printing" title=
"Chapter 11. Samba Printing Internals">Samba Printing Internals
</a></span></dt><dd><div class=
"itemizedlist"><ul type=
"disc"><li><p>Gerald Carter
</p></li></ul></div></dd><dt><span class=
"term"><a href=
"#wins" title=
"Chapter 12. Samba WINS Internals">Samba WINS Internals
</a></span></dt><dd><div class=
"itemizedlist"><ul type=
"disc"><li><p>Gerald Carter
</p></li></ul></div></dd><dt><span class=
"term"><a href=
"#sam" title=
"Chapter 13. The Upcoming SAM System">The Upcoming SAM System
</a></span></dt><dd><div class=
"itemizedlist"><ul type=
"disc"><li><p>Andrew Bartlett
</p></li></ul></div></dd><dt><span class=
"term"><a href=
"#pwencrypt" title=
"Chapter 14. LanMan and NT Password Encryption">LanMan and NT Password Encryption
</a></span></dt><dd><div class=
"itemizedlist"><ul type=
"disc"><li><p>Jeremy Allison
<<a href=
"mailto:samba@samba.org" target=
"_top">samba@samba.org
</a>></p></li></ul></div></dd><dt><span class=
"term"><a href=
"#modules" title=
"Chapter 15. Modules">Modules
</a></span></dt><dd><div class=
"itemizedlist"><ul type=
"disc"><li><p>Jelmer Vernooij
<<a href=
"mailto:jelmer@samba.org" target=
"_top">jelmer@samba.org
</a>></p></li></ul></div></dd><dt><span class=
"term"><a href=
"#rpc-plugin" title=
"Chapter 16. RPC Pluggable Modules">RPC Pluggable Modules
</a></span></dt><dd><div class=
"itemizedlist"><ul type=
"disc"><li><p>Anthony Liguori
<<a href=
"mailto:aliguor@us.ibm.com" target=
"_top">aliguor@us.ibm.com
</a>></p></li><li><p>Jelmer Vernooij
<<a href=
"mailto:jelmer@samba.org" target=
"_top">jelmer@samba.org
</a>></p></li></ul></div></dd><dt><span class=
"term"><a href=
"#vfs" title=
"Chapter 17. VFS Modules">VFS Modules
</a></span></dt><dd><div class=
"itemizedlist"><ul type=
"disc"><li><p>Alexander Bokovoy
<<a href=
"mailto:ab@samba.org" target=
"_top">ab@samba.org
</a>></p></li><li><p>Stefan Metzmacher
<<a href=
"mailto:metze@metzemix.de" target=
"_top">metze@metzemix.de
</a>></p></li></ul></div></dd><dt><span class=
"term"><a href=
"#Packaging" title=
"Chapter 18. Notes to packagers">Notes to packagers
</a></span></dt><dd><div class=
"itemizedlist"><ul type=
"disc"><li><p>Jelmer Vernooij
</p></li></ul></div></dd><dt><span class=
"term"><a href=
"#contributing" title=
"Chapter 19. Contributing code">Contributing code
</a></span></dt><dd><div class=
"itemizedlist"><ul type=
"disc"><li><p>Jelmer Vernooij
<<a href=
"mailto:jelmer@samba.org" target=
"_top">jelmer@samba.org
</a>></p></li></ul></div></dd></dl></div><p>
18 </p></div></div><div><div class=
"abstract"><p class=
"title"><b>Abstract
</b></p><p>
19 <span class=
"emphasis"><em>Last Update
</em></span> : Fri Jun
6 00:
45:
54 CEST
2003
21 This book is a collection of documents that might be useful for
22 people developing samba or those interested in doing so.
23 It's nothing more than a collection of documents written by samba developers about
24 the internals of various parts of samba and the SMB protocol. It's still incomplete.
25 The most recent version of this document
26 can be found at
<a href=
"http://devel.samba.org/" target=
"_top">http://devel.samba.org/
</a>.
27 Please send updates to
<a href=
"mailto:jelmer@samba.org" target=
"_top">Jelmer Vernooij
</a>.
29 This documentation is distributed under the GNU General Public License (GPL)
30 version
2. A copy of the license is included with the Samba source
31 distribution. A copy can be found on-line at
<a href=
"http://www.fsf.org/licenses/gpl.txt" target=
"_top">http://www.fsf.org/licenses/gpl.txt
</a>
32 </p></div></div></div><div></div><hr></div><div class=
"toc"><p><b>Table of Contents
</b></p><dl><dt>1.
<a href=
"#netbios">Definition of NetBIOS Protocol and Name Resolution Modes
</a></dt><dd><dl><dt><a href=
"#id2800515">NETBIOS
</a></dt><dt><a href=
"#id2800602">BROADCAST NetBIOS
</a></dt><dt><a href=
"#id2800633">NBNS NetBIOS
</a></dt></dl></dd><dt>2.
<a href=
"#architecture">Samba Architecture
</a></dt><dd><dl><dt><a href=
"#id2797071">Introduction
</a></dt><dt><a href=
"#id2797281">Multithreading and Samba
</a></dt><dt><a href=
"#id2797319">Threading smbd
</a></dt><dt><a href=
"#id2797394">Threading nmbd
</a></dt><dt><a href=
"#id2797461">nbmd Design
</a></dt></dl></dd><dt>3.
<a href=
"#debug">The samba DEBUG system
</a></dt><dd><dl><dt><a href=
"#id2796882">New Output Syntax
</a></dt><dt><a href=
"#id2797018">The DEBUG() Macro
</a></dt><dt><a href=
"#id2867347">The DEBUGADD() Macro
</a></dt><dt><a href=
"#id2867392">The DEBUGLVL() Macro
</a></dt><dt><a href=
"#id2867497">New Functions
</a></dt><dd><dl><dt><a href=
"#id2867504">dbgtext()
</a></dt><dt><a href=
"#id2867524">dbghdr()
</a></dt><dt><a href=
"#id2867547">format_debug_text()
</a></dt></dl></dd></dl></dd><dt>4.
<a href=
"#CodingSuggestions">Coding Suggestions
</a></dt><dt>5.
<a href=
"#internals">Samba Internals
</a></dt><dd><dl><dt><a href=
"#id2866920">Character Handling
</a></dt><dt><a href=
"#id2866946">The new functions
</a></dt><dt><a href=
"#id2868198">Macros in byteorder.h
</a></dt><dd><dl><dt><a href=
"#id2869122">CVAL(buf,pos)
</a></dt><dt><a href=
"#id2869136">PVAL(buf,pos)
</a></dt><dt><a href=
"#id2869150">SCVAL(buf,pos,val)
</a></dt><dt><a href=
"#id2869163">SVAL(buf,pos)
</a></dt><dt><a href=
"#id2869179">IVAL(buf,pos)
</a></dt><dt><a href=
"#id2869193">SVALS(buf,pos)
</a></dt><dt><a href=
"#id2869208">IVALS(buf,pos)
</a></dt><dt><a href=
"#id2869222">SSVAL(buf,pos,val)
</a></dt><dt><a href=
"#id2869236">SIVAL(buf,pos,val)
</a></dt><dt><a href=
"#id2869251">SSVALS(buf,pos,val)
</a></dt><dt><a href=
"#id2869265">SIVALS(buf,pos,val)
</a></dt><dt><a href=
"#id2869280">RSVAL(buf,pos)
</a></dt><dt><a href=
"#id2869294">RIVAL(buf,pos)
</a></dt><dt><a href=
"#id2869308">RSSVAL(buf,pos,val)
</a></dt><dt><a href=
"#id2869323">RSIVAL(buf,pos,val)
</a></dt></dl></dd><dt><a href=
"#id2869339">LAN Manager Samba API
</a></dt><dd><dl><dt><a href=
"#id2869375">Parameters
</a></dt><dt><a href=
"#id2869526">Return value
</a></dt></dl></dd><dt><a href=
"#id2869611">Code character table
</a></dt></dl></dd><dt>6.
<a href=
"#parsing">The smb.conf file
</a></dt><dd><dl><dt><a href=
"#id2868950">Lexical Analysis
</a></dt><dd><dl><dt><a href=
"#id2869043">Handling of Whitespace
</a></dt><dt><a href=
"#id2869099">Handling of Line Continuation
</a></dt><dt><a href=
"#id2870758">Line Continuation Quirks
</a></dt></dl></dd><dt><a href=
"#id2870856">Syntax
</a></dt><dd><dl><dt><a href=
"#id2870928">About params.c
</a></dt></dl></dd></dl></dd><dt>7.
<a href=
"#unix-smb">NetBIOS in a Unix World
</a></dt><dd><dl><dt><a href=
"#id2870375">Introduction
</a></dt><dt><a href=
"#id2870400">Usernames
</a></dt><dt><a href=
"#id2870628">File Ownership
</a></dt><dt><a href=
"#id2870665">Passwords
</a></dt><dt><a href=
"#id2870702">Locking
</a></dt><dt><a href=
"#id2871641">Deny Modes
</a></dt><dt><a href=
"#id2871672">Trapdoor UIDs
</a></dt><dt><a href=
"#id2871697">Port numbers
</a></dt><dt><a href=
"#id2871742">Protocol Complexity
</a></dt></dl></dd><dt>8.
<a href=
"#tracing">Tracing samba system calls
</a></dt><dt>9.
<a href=
"#windows-debug">Finding useful information on windows
</a></dt><dd><dl><dt><a href=
"#id2871397">Netlogon debugging output
</a></dt></dl></dd><dt>10.
<a href=
"#ntdomain">NT Domain RPC's
</a></dt><dd><dl><dt><a href=
"#id2872364">Introduction
</a></dt><dd><dl><dt><a href=
"#id2873295">Sources
</a></dt><dt><a href=
"#id2873330">Credits
</a></dt></dl></dd><dt><a href=
"#id2873367">Notes and Structures
</a></dt><dd><dl><dt><a href=
"#id2873375">Notes
</a></dt><dt><a href=
"#id2873451">Enumerations
</a></dt><dt><a href=
"#id2873665">Structures
</a></dt></dl></dd><dt><a href=
"#id2876614">MSRPC over Transact Named Pipe
</a></dt><dd><dl><dt><a href=
"#id2876627">MSRPC Pipes
</a></dt><dt><a href=
"#id2876729">Header
</a></dt><dt><a href=
"#id2877600">Tail
</a></dt><dt><a href=
"#id2877647">RPC Bind / Bind Ack
</a></dt><dt><a href=
"#id2877826">NTLSA Transact Named Pipe
</a></dt><dt><a href=
"#id2877991">LSA Open Policy
</a></dt><dt><a href=
"#id2878118">LSA Query Info Policy
</a></dt><dt><a href=
"#id2878223">LSA Enumerate Trusted Domains
</a></dt><dt><a href=
"#id2878315">LSA Open Secret
</a></dt><dt><a href=
"#id2878424">LSA Close
</a></dt><dt><a href=
"#id2878490">LSA Lookup SIDS
</a></dt><dt><a href=
"#id2878700">LSA Lookup Names
</a></dt></dl></dd><dt><a href=
"#id2878926">NETLOGON rpc Transact Named Pipe
</a></dt><dd><dl><dt><a href=
"#id2879087">LSA Request Challenge
</a></dt><dt><a href=
"#id2879222">LSA Authenticate
2</a></dt><dt><a href=
"#id2879369">LSA Server Password Set
</a></dt><dt><a href=
"#id2879484">LSA SAM Logon
</a></dt><dt><a href=
"#id2879598">LSA SAM Logoff
</a></dt></dl></dd><dt><a href=
"#id2879689">\\MAILSLOT\NET\NTLOGON
</a></dt><dd><dl><dt><a href=
"#id2879701">Query for PDC
</a></dt><dt><a href=
"#id2879969">SAM Logon
</a></dt></dl></dd><dt><a href=
"#id2880294">SRVSVC Transact Named Pipe
</a></dt><dd><dl><dt><a href=
"#id2880339">Net Share Enum
</a></dt><dt><a href=
"#id2880558">Net Server Get Info
</a></dt></dl></dd><dt><a href=
"#id2880674">Cryptographic side of NT Domain Authentication
</a></dt><dd><dl><dt><a href=
"#id2880682">Definitions
</a></dt><dt><a href=
"#id2880845">Protocol
</a></dt><dt><a href=
"#id2880942">Comments
</a></dt></dl></dd><dt><a href=
"#id2880991">SIDs and RIDs
</a></dt><dd><dl><dt><a href=
"#id2881031">Well-known SIDs
</a></dt><dt><a href=
"#id2881346">Well-known RIDS
</a></dt></dl></dd></dl></dd><dt>11.
<a href=
"#printing">Samba Printing Internals
</a></dt><dd><dl><dt><a href=
"#id2890028">Abstract
</a></dt><dt><a href=
"#id2890044">
33 Printing Interface to Various Back ends
34 </a></dt><dt><a href=
"#id2890298">
36 </a></dt><dt><a href=
"#id2890507">
37 ChangeID and Client Caching of Printer Information
38 </a></dt><dt><a href=
"#id2890520">
39 Windows NT/
2K Printer Change Notify
40 </a></dt></dl></dd><dt>12.
<a href=
"#wins">Samba WINS Internals
</a></dt><dd><dl><dt><a href=
"#id2889988">WINS Failover
</a></dt></dl></dd><dt>13.
<a href=
"#sam">The Upcoming SAM System
</a></dt><dd><dl><dt><a href=
"#id2889789">Security in the 'new SAM'
</a></dt><dt><a href=
"#id2891316">Standalone from UNIX
</a></dt><dt><a href=
"#id2891349">Handles and Races in the new SAM
</a></dt><dt><a href=
"#id2891418">Layers
</a></dt><dd><dl><dt><a href=
"#id2891425">Application
</a></dt><dt><a href=
"#id2891441">SAM Interface
</a></dt><dt><a href=
"#id2891468">SAM Modules
</a></dt></dl></dd><dt><a href=
"#id2891490">SAM Modules
</a></dt><dd><dl><dt><a href=
"#id2891497">Special Module: sam_passdb
</a></dt><dt><a href=
"#id2891516">sam_ads
</a></dt></dl></dd><dt><a href=
"#id2891555">Memory Management
</a></dt><dt><a href=
"#id2891645">Testing
</a></dt></dl></dd><dt>14.
<a href=
"#pwencrypt">LanMan and NT Password Encryption
</a></dt><dd><dl><dt><a href=
"#id2892285">Introduction
</a></dt><dt><a href=
"#id2892310">How does it work?
</a></dt><dt><a href=
"#id2891197">The smbpasswd file
</a></dt></dl></dd><dt>15.
<a href=
"#modules">Modules
</a></dt><dd><dl><dt><a href=
"#id2892236">Advantages
</a></dt><dt><a href=
"#id2893136">Loading modules
</a></dt><dd><dl><dt><a href=
"#id2893169">Static modules
</a></dt><dt><a href=
"#id2894111">Shared modules
</a></dt></dl></dd><dt><a href=
"#id2894139">Writing modules
</a></dt><dd><dl><dt><a href=
"#id2894200">Static/Shared selection in configure.in
</a></dt></dl></dd></dl></dd><dt>16.
<a href=
"#rpc-plugin">RPC Pluggable Modules
</a></dt><dd><dl><dt><a href=
"#id2892904">About
</a></dt><dt><a href=
"#id2892923">General Overview
</a></dt></dl></dd><dt>17.
<a href=
"#vfs">VFS Modules
</a></dt><dd><dl><dt><a href=
"#id2895215">The Samba (Posix) VFS layer
</a></dt><dd><dl><dt><a href=
"#id2895223">The general interface
</a></dt><dt><a href=
"#id2895338">Possible VFS operation layers
</a></dt></dl></dd><dt><a href=
"#id2895409">The Interaction between the Samba VFS subsystem and the modules
</a></dt><dd><dl><dt><a href=
"#id2895418">Initialization and registration
</a></dt><dt><a href=
"#id2895609">How the Modules handle per connection data
</a></dt></dl></dd><dt><a href=
"#id2895852">Upgrading to the New VFS Interface
</a></dt><dd><dl><dt><a href=
"#id2895860">Upgrading from
2.2.* and
3.0aplha modules
</a></dt></dl></dd><dt><a href=
"#id2896401">Some Notes
</a></dt><dd><dl><dt><a href=
"#id2896408">Implement TRANSPARENT functions
</a></dt><dt><a href=
"#id2896432">Implement OPAQUE functions
</a></dt></dl></dd></dl></dd><dt>18.
<a href=
"#Packaging">Notes to packagers
</a></dt><dd><dl><dt><a href=
"#id2895009">Versioning
</a></dt><dt><a href=
"#id2895042">Modules
</a></dt></dl></dd><dt>19.
<a href=
"#contributing">Contributing code
</a></dt></dl></div><div class=
"chapter" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title"><a name=
"netbios"></a>Chapter
1. Definition of NetBIOS Protocol and Name Resolution Modes
</h2></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Luke
</span> <span class=
"surname">Leighton
</span></h3></div></div><div><p class=
"pubdate">12 June
1997</p></div></div><div></div></div><div class=
"toc"><p><b>Table of Contents
</b></p><dl><dt><a href=
"#id2800515">NETBIOS
</a></dt><dt><a href=
"#id2800602">BROADCAST NetBIOS
</a></dt><dt><a href=
"#id2800633">NBNS NetBIOS
</a></dt></dl></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2800515"></a>NETBIOS
</h2></div></div><div></div></div><p>
41 NetBIOS runs over the following tranports: TCP/IP; NetBEUI and IPX/SPX.
42 Samba only uses NetBIOS over TCP/IP. For details on the TCP/IP NetBIOS
43 Session Service NetBIOS Datagram Service, and NetBIOS Names, see
44 rfc1001.txt and rfc1002.txt.
46 NetBEUI is a raw NetBIOS frame protocol implementation that allows NetBIOS
47 datagrams to be sent out over the 'wire' embedded within LLC frames.
48 NetBEUI is not required when using NetBIOS over TCP/IP protocols and it
49 is preferable NOT to install NetBEUI if it can be avoided.
51 IPX/SPX is also not required when using NetBIOS over TCP/IP, and it is
52 preferable NOT to install the IPX/SPX transport unless you are using Novell
53 servers. At the very least, it is recommended that you do not install
54 'NetBIOS over IPX/SPX'.
56 [When installing Windows
95, you will find that NetBEUI and IPX/SPX are
57 installed as the default protocols. This is because they are the simplest
58 to manage: no Windows
95 user-configuration is required].
60 NetBIOS applications (such as samba) offer their services (for example,
61 SMB file and print sharing) on a NetBIOS name. They must claim this name
62 on the network before doing so. The NetBIOS session service will then
63 accept connections on the application's behalf (on the NetBIOS name
64 claimed by the application). A NetBIOS session between the application
65 and the client can then commence.
67 NetBIOS names consist of
15 characters plus a 'type' character. This is
68 similar, in concept, to an IP address and a TCP port number, respectively.
69 A NetBIOS-aware application on a host will offer different services under
70 different NetBIOS name types, just as a host will offer different TCP/IP
71 services on different port numbers.
73 NetBIOS names must be claimed on a network, and must be defended. The use
74 of NetBIOS names is most suitable on a single subnet; a Local Area Network
75 or a Wide Area Network.
77 NetBIOS names are either UNIQUE or GROUP. Only one application can claim a
78 UNIQUE NetBIOS name on a network.
80 There are two kinds of NetBIOS Name resolution: Broadcast and Point-to-Point.
81 </p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2800602"></a>BROADCAST NetBIOS
</h2></div></div><div></div></div><p>
82 Clients can claim names, and therefore offer services on successfully claimed
83 names, on their broadcast-isolated subnet. One way to get NetBIOS services
84 (such as browsing: see ftp.microsoft.com/drg/developr/CIFS/browdiff.txt; and
85 SMB file/print sharing: see cifs4.txt) working on a LAN or WAN is to make
86 your routers forward all broadcast packets from TCP/IP ports
137,
138 and
139.
88 This, however, is not recommended. If you have a large LAN or WAN, you will
89 find that some of your hosts spend
95 percent of their time dealing with
90 broadcast traffic. [If you have IPX/SPX on your LAN or WAN, you will find
91 that this is already happening: a packet analyzer will show, roughly
92 every twelve minutes, great swathes of broadcast traffic!].
93 </p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2800633"></a>NBNS NetBIOS
</h2></div></div><div></div></div><p>
94 rfc1001.txt describes, amongst other things, the implementation and use
95 of, a 'NetBIOS Name Service'. NT/AS offers 'Windows Internet Name Service'
96 which is fully rfc1001/
2 compliant, but has had to take specific action
97 with certain NetBIOS names in order to make it useful. (for example, it
98 deals with the registration of
<1c
> <1d
> <1e
> names all in different ways.
99 I recommend the reading of the Microsoft WINS Server Help files for full
102 The use of a WINS server cuts down on broadcast network traffic for
103 NetBIOS name resolution. It has the effect of pulling all the broadcast
104 isolated subnets together into a single NetBIOS scope, across your LAN
105 or WAN, while avoiding the use of TCP/IP broadcast packets.
107 When you have a WINS server on your LAN, WINS clients will be able to
108 contact the WINS server to resolve NetBIOS names. Note that only those
109 WINS clients that have registered with the same WINS server will be
110 visible. The WINS server _can_ have static NetBIOS entries added to its
111 database (usually for security reasons you might want to consider putting
112 your domain controllers or other important servers as static entries,
113 but you should not rely on this as your sole means of security), but for
114 the most part, NetBIOS names are registered dynamically.
116 This provides some confusion for lots of people, and is worth mentioning
117 here: a Browse Server is NOT a WINS Server, even if these services are
118 implemented in the same application. A Browse Server _needs_ a WINS server
119 because a Browse Server is a WINS client, which is _not_ the same thing].
121 Clients can claim names, and therefore offer services on successfully claimed
122 names, on their broadcast-isolated subnet. One way to get NetBIOS services
123 (such as browsing: see ftp.microsoft.com/drg/developr/CIFS/browdiff.txt; and
124 SMB file/print sharing: see cifs6.txt) working on a LAN or WAN is to make
125 your routers forward all broadcast packets from TCP/IP ports
137,
138 and
139.
126 You will find, however, if you do this on a large LAN or a WAN, that your
127 network is completely swamped by NetBIOS and browsing packets, which is why
128 WINS was developed to minimise the necessity of broadcast traffic.
130 WINS Clients therefore claim names from the WINS server. If the WINS
131 server allows them to register a name, the client's NetBIOS session service
132 can then offer services on this name. Other WINS clients will then
133 contact the WINS server to resolve a NetBIOS name.
134 </p></div></div><div class=
"chapter" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title"><a name=
"architecture"></a>Chapter
2. Samba Architecture
</h2></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Dan
</span> <span class=
"surname">Shearer
</span></h3></div></div><div><p class=
"pubdate"> November
1997</p></div></div><div></div></div><div class=
"toc"><p><b>Table of Contents
</b></p><dl><dt><a href=
"#id2797071">Introduction
</a></dt><dt><a href=
"#id2797281">Multithreading and Samba
</a></dt><dt><a href=
"#id2797319">Threading smbd
</a></dt><dt><a href=
"#id2797394">Threading nmbd
</a></dt><dt><a href=
"#id2797461">nbmd Design
</a></dt></dl></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2797071"></a>Introduction
</h2></div></div><div></div></div><p>
135 This document gives a general overview of how Samba works
136 internally. The Samba Team has tried to come up with a model which is
137 the best possible compromise between elegance, portability, security
138 and the constraints imposed by the very messy SMB and CIFS
141 It also tries to answer some of the frequently asked questions such as:
142 </p><div class=
"orderedlist"><ol type=
"1"><li><p>
143 Is Samba secure when running on Unix? The xyz platform?
144 What about the root priveliges issue?
145 </p></li><li><p>Pros and cons of multithreading in various parts of Samba
</p></li><li><p>Why not have a separate process for name resolution, WINS, and browsing?
</p></li></ol></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2797281"></a>Multithreading and Samba
</h2></div></div><div></div></div><p>
146 People sometimes tout threads as a uniformly good thing. They are very
147 nice in their place but are quite inappropriate for smbd. nmbd is
148 another matter, and multi-threading it would be very nice.
150 The short version is that smbd is not multithreaded, and alternative
151 servers that take this approach under Unix (such as Syntax, at the
152 time of writing) suffer tremendous performance penalties and are less
153 robust. nmbd is not threaded either, but this is because it is not
154 possible to do it while keeping code consistent and portable across
35
155 or more platforms. (This drawback also applies to threading smbd.)
157 The longer versions is that there are very good reasons for not making
158 smbd multi-threaded. Multi-threading would actually make Samba much
159 slower, less scalable, less portable and much less robust. The fact
160 that we use a separate process for each connection is one of Samba's
162 </p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2797319"></a>Threading smbd
</h2></div></div><div></div></div><p>
163 A few problems that would arise from a threaded smbd are:
164 </p><div class=
"orderedlist"><ol type=
"1"><li><p>
165 It's not only to create threads instead of processes, but you
166 must care about all variables if they have to be thread specific
167 (currently they would be global).
169 if one thread dies (eg. a seg fault) then all threads die. We can
170 immediately throw robustness out the window.
172 many of the system calls we make are blocking. Non-blocking
173 equivalents of many calls are either not available or are awkward (and
174 slow) to use. So while we block in one thread all clients are
175 waiting. Imagine if one share is a slow NFS filesystem and the others
176 are fast, we will end up slowing all clients to the speed of NFS.
178 you can't run as a different uid in different threads. This means
179 we would have to switch uid/gid on _every_ SMB packet. It would be
182 the per process file descriptor limit would mean that we could only
183 support a limited number of clients.
185 we couldn't use the system locking calls as the locking context of
186 fcntl() is a process, not a thread.
187 </p></li></ol></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2797394"></a>Threading nmbd
</h2></div></div><div></div></div><p>
188 This would be ideal, but gets sunk by portability requirements.
190 Andrew tried to write a test threads library for nmbd that used only
191 ansi-C constructs (using setjmp and longjmp). Unfortunately some OSes
192 defeat this by restricting longjmp to calling addresses that are
193 shallower than the current address on the stack (apparently AIX does
194 this). This makes a truly portable threads library impossible. So to
195 support all our current platforms we would have to code nmbd both with
196 and without threads, and as the real aim of threads is to make the
197 code clearer we would not have gained anything. (it is a myth that
198 threads make things faster. threading is like recursion, it can make
199 things clear but the same thing can always be done faster by some
202 Chris tried to spec out a general design that would abstract threading
203 vs separate processes (vs other methods?) and make them accessible
204 through some general API. This doesn't work because of the data
205 sharing requirements of the protocol (packets in the future depending
206 on packets now, etc.) At least, the code would work but would be very
207 clumsy, and besides the fork() type model would never work on Unix. (Is there an OS that it would work on, for nmbd?)
209 A fork() is cheap, but not nearly cheap enough to do on every UDP
210 packet that arrives. Having a pool of processes is possible but is
211 nasty to program cleanly due to the enormous amount of shared data (in
212 complex structures) between the processes. We can't rely on each
213 platform having a shared memory system.
214 </p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2797461"></a>nbmd Design
</h2></div></div><div></div></div><p>
215 Originally Andrew used recursion to simulate a multi-threaded
216 environment, which use the stack enormously and made for really
217 confusing debugging sessions. Luke Leighton rewrote it to use a
218 queuing system that keeps state information on each packet. The
219 first version used a single structure which was used by all the
220 pending states. As the initialisation of this structure was
221 done by adding arguments, as the functionality developed, it got
222 pretty messy. So, it was replaced with a higher-order function
223 and a pointer to a user-defined memory block. This suddenly
224 made things much simpler: large numbers of functions could be
225 made static, and modularised. This is the same principle as used
226 in NT's kernel, and achieves the same effect as threads, but in
229 Then Jeremy rewrote nmbd. The packet data in nmbd isn't what's on the
230 wire. It's a nice format that is very amenable to processing but still
231 keeps the idea of a distinct packet. See
"struct packet_struct
" in
232 nameserv.h. It has all the detail but none of the on-the-wire
233 mess. This makes it ideal for using in disk or memory-based databases
234 for browsing and WINS support.
235 </p></div></div><div class=
"chapter" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title"><a name=
"debug"></a>Chapter
3. The samba DEBUG system
</h2></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Chris
</span> <span class=
"surname">Hertel
</span></h3></div></div><div><p class=
"pubdate">July
1998</p></div></div><div></div></div><div class=
"toc"><p><b>Table of Contents
</b></p><dl><dt><a href=
"#id2796882">New Output Syntax
</a></dt><dt><a href=
"#id2797018">The DEBUG() Macro
</a></dt><dt><a href=
"#id2867347">The DEBUGADD() Macro
</a></dt><dt><a href=
"#id2867392">The DEBUGLVL() Macro
</a></dt><dt><a href=
"#id2867497">New Functions
</a></dt><dd><dl><dt><a href=
"#id2867504">dbgtext()
</a></dt><dt><a href=
"#id2867524">dbghdr()
</a></dt><dt><a href=
"#id2867547">format_debug_text()
</a></dt></dl></dd></dl></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2796882"></a>New Output Syntax
</h2></div></div><div></div></div><p>
236 The syntax of a debugging log file is represented as:
237 </p><pre class=
"programlisting">
238 >debugfile
< :== {
>debugmsg
< }
240 >debugmsg
< :==
>debughdr
< '\n'
>debugtext
<
242 >debughdr
< :== '[' TIME ',' LEVEL ']' FILE ':' [FUNCTION] '(' LINE ')'
244 >debugtext
< :== {
>debugline
< }
246 >debugline
< :== TEXT '\n'
248 TEXT is a string of characters excluding the newline character.
250 LEVEL is the DEBUG level of the message (an integer in the range
255 FILE is the name of the file from which the debug message was
258 FUNCTION is the function from which the debug message was generated.
260 LINE is the line number of the debug statement that generated the
262 </p><p>Basically, what that all means is:
</p><div class=
"orderedlist"><ol type=
"1"><li><p>
263 A debugging log file is made up of debug messages.
265 Each debug message is made up of a header and text. The header is
266 separated from the text by a newline.
268 The header begins with the timestamp and debug level of the
269 message enclosed in brackets. The filename, function, and line
270 number at which the message was generated follow. The filename is
271 terminated by a colon, and the function name is terminated by the
272 parenthesis which contain the line number. Depending upon the
273 compiler, the function name may be missing (it is generated by the
274 __FUNCTION__ macro, which is not universally implemented, dangit).
276 The message text is made up of zero or more lines, each terminated
278 </p></li></ol></div><p>Here's some example output:
</p><pre class=
"programlisting">
279 [
1998/
08/
03 12:
55:
25,
1] nmbd.c:(
659)
280 Netbios nameserver version
1.9.19-prealpha started.
281 Copyright Andrew Tridgell
1994-
1997
282 [
1998/
08/
03 12:
55:
25,
3] loadparm.c:(
763)
283 Initializing global parameters
285 Note that in the above example the function names are not listed on
286 the header line. That's because the example above was generated on an
287 SGI Indy, and the SGI compiler doesn't support the __FUNCTION__ macro.
288 </p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2797018"></a>The DEBUG() Macro
</h2></div></div><div></div></div><p>
289 Use of the DEBUG() macro is unchanged. DEBUG() takes two parameters.
290 The first is the message level, the second is the body of a function
291 call to the Debug1() function.
292 </p><p>That's confusing.
</p><p>Here's an example which may help a bit. If you would write
</p><pre class=
"programlisting">
293 printf(
"This is a %s message.\n
",
"debug
" );
295 to send the output to stdout, then you would write
296 </p><pre class=
"programlisting">
297 DEBUG(
0, (
"This is a %s message.\n
",
"debug
" ) );
299 to send the output to the debug file. All of the normal printf()
300 formatting escapes work.
302 Note that in the above example the DEBUG message level is set to
0.
303 Messages at level
0 always print. Basically, if the message level is
304 less than or equal to the global value DEBUGLEVEL, then the DEBUG
305 statement is processed.
307 The output of the above example would be something like:
308 </p><pre class=
"programlisting">
309 [
1998/
07/
30 16:
00:
51,
0] file.c:function(
128)
310 This is a debug message.
312 Each call to DEBUG() creates a new header *unless* the output produced
313 by the previous call to DEBUG() did not end with a '\n'. Output to the
314 debug file is passed through a formatting buffer which is flushed
315 every time a newline is encountered. If the buffer is not empty when
316 DEBUG() is called, the new input is simply appended.
318 ...but that's really just a Kludge. It was put in place because
319 DEBUG() has been used to write partial lines. Here's a simple (dumb)
320 example of the kind of thing I'm talking about:
321 </p><pre class=
"programlisting">
322 DEBUG(
0, (
"The test returned
" ) );
324 DEBUG(
0, (
"True
") );
326 DEBUG(
0, (
"False
") );
327 DEBUG(
0, (
".\n
") );
329 Without the format buffer, the output (assuming test() returned true)
330 would look like this:
331 </p><pre class=
"programlisting">
332 [
1998/
07/
30 16:
00:
51,
0] file.c:function(
256)
334 [
1998/
07/
30 16:
00:
51,
0] file.c:function(
258)
336 [
1998/
07/
30 16:
00:
51,
0] file.c:function(
261)
338 </pre><p>Which isn't much use. The format buffer kludge fixes this problem.
339 </p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2867347"></a>The DEBUGADD() Macro
</h2></div></div><div></div></div><p>
340 In addition to the kludgey solution to the broken line problem
341 described above, there is a clean solution. The DEBUGADD() macro never
342 generates a header. It will append new text to the current debug
343 message even if the format buffer is empty. The syntax of the
344 DEBUGADD() macro is the same as that of the DEBUG() macro.
345 </p><pre class=
"programlisting">
346 DEBUG(
0, (
"This is the first line.\n
" ) );
347 DEBUGADD(
0, (
"This is the second line.\nThis is the third line.\n
" ) );
348 </pre><p>Produces
</p><pre class=
"programlisting">
349 [
1998/
07/
30 16:
00:
51,
0] file.c:function(
512)
350 This is the first line.
351 This is the second line.
352 This is the third line.
353 </pre></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2867392"></a>The DEBUGLVL() Macro
</h2></div></div><div></div></div><p>
354 One of the problems with the DEBUG() macro was that DEBUG() lines
355 tended to get a bit long. Consider this example from
357 </p><pre class=
"programlisting">
358 DEBUG(
3,(
"send_local_master_announcement: type %x for name %s on subnet %s for workgroup %s\n
",
359 type, global_myname, subrec-
>subnet_name, work-
>work_group));
361 One solution to this is to break it down using DEBUG() and DEBUGADD(),
363 </p><pre class=
"programlisting">
364 DEBUG(
3, (
"send_local_master_announcement:
" ) );
365 DEBUGADD(
3, (
"type %x for name %s
", type, global_myname ) );
366 DEBUGADD(
3, (
"on subnet %s
", subrec-
>subnet_name ) );
367 DEBUGADD(
3, (
"for workgroup %s\n
", work-
>work_group ) );
369 A similar, but arguably nicer approach is to use the DEBUGLVL() macro.
370 This macro returns True if the message level is less than or equal to
371 the global DEBUGLEVEL value, so:
372 </p><pre class=
"programlisting">
375 dbgtext(
"send_local_master_announcement:
" );
376 dbgtext(
"type %x for name %s
", type, global_myname );
377 dbgtext(
"on subnet %s
", subrec-
>subnet_name );
378 dbgtext(
"for workgroup %s\n
", work-
>work_group );
380 </pre><p>(The dbgtext() function is explained below.)
</p><p>There are a few advantages to this scheme:
</p><div class=
"orderedlist"><ol type=
"1"><li><p>
381 The test is performed only once.
383 You can allocate variables off of the stack that will only be used
384 within the DEBUGLVL() block.
386 Processing that is only relevant to debug output can be contained
387 within the DEBUGLVL() block.
388 </p></li></ol></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2867497"></a>New Functions
</h2></div></div><div></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2867504"></a>dbgtext()
</h3></div></div><div></div></div><p>
389 This function prints debug message text to the debug file (and
390 possibly to syslog) via the format buffer. The function uses a
391 variable argument list just like printf() or Debug1(). The
392 input is printed into a buffer using the vslprintf() function,
393 and then passed to format_debug_text().
395 If you use DEBUGLVL() you will probably print the body of the
396 message using dbgtext().
397 </p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2867524"></a>dbghdr()
</h3></div></div><div></div></div><p>
398 This is the function that writes a debug message header.
399 Headers are not processed via the format buffer. Also note that
400 if the format buffer is not empty, a call to dbghdr() will not
401 produce any output. See the comments in dbghdr() for more info.
403 It is not likely that this function will be called directly. It
404 is used by DEBUG() and DEBUGADD().
405 </p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2867547"></a>format_debug_text()
</h3></div></div><div></div></div><p>
406 This is a static function in debug.c. It stores the output text
407 for the body of the message in a buffer until it encounters a
408 newline. When the newline character is found, the buffer is
409 written to the debug file via the Debug1() function, and the
410 buffer is reset. This allows us to add the indentation at the
411 beginning of each line of the message body, and also ensures
412 that the output is written a line at a time (which cleans up
414 </p></div></div></div><div class=
"chapter" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title"><a name=
"CodingSuggestions"></a>Chapter
4. Coding Suggestions
</h2></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Steve
</span> <span class=
"surname">French
</span></h3></div></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Simo
</span> <span class=
"surname">Sorce
</span></h3></div></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Andrew
</span> <span class=
"surname">Bartlett
</span></h3></div></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Tim
</span> <span class=
"surname">Potter
</span></h3></div></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Martin
</span> <span class=
"surname">Pool
</span></h3></div></div></div><div></div></div><p>
415 So you want to add code to Samba ...
417 One of the daunting tasks facing a programmer attempting to write code for
418 Samba is understanding the various coding conventions used by those most
419 active in the project. These conventions were mostly unwritten and helped
420 improve either the portability, stability or consistency of the code. This
421 document will attempt to document a few of the more important coding
422 practices used at this time on the Samba project. The coding practices are
423 expected to change slightly over time, and even to grow as more is learned
424 about obscure portability considerations. Two existing documents
425 <tt class=
"filename">samba/source/internals.doc
</tt> and
426 <tt class=
"filename">samba/source/architecture.doc
</tt> provide
427 additional information.
429 The loosely related question of coding style is very personal and this
430 document does not attempt to address that subject, except to say that I
431 have observed that eight character tabs seem to be preferred in Samba
432 source. If you are interested in the topic of coding style, two oft-quoted
435 <a href=
"http://lxr.linux.no/source/Documentation/CodingStyle" target=
"_top">http://lxr.linux.no/source/Documentation/CodingStyle
</a>
437 <a href=
"http://www.fsf.org/prep/standards_toc.html" target=
"_top">http://www.fsf.org/prep/standards_toc.html
</a>
439 But note that coding style in Samba varies due to the many different
440 programmers who have contributed.
442 Following are some considerations you should use when adding new code to
443 Samba. First and foremost remember that:
445 Portability is a primary consideration in adding function, as is network
446 compatability with de facto, existing, real world CIFS/SMB implementations.
447 There are lots of platforms that Samba builds on so use caution when adding
448 a call to a library function that is not invoked in existing Samba code.
449 Also note that there are many quite different SMB/CIFS clients that Samba
450 tries to support, not all of which follow the SNIA CIFS Technical Reference
451 (or the earlier Microsoft reference documents or the X/Open book on the SMB
454 Here are some other suggestions:
455 </p><div class=
"orderedlist"><ol type=
"1"><li><p>
456 use d_printf instead of printf for display text
457 reason: enable auto-substitution of translated language text
459 use SAFE_FREE instead of free
460 reason: reduce traps due to null pointers
462 don't use bzero use memset, or ZERO_STRUCT and ZERO_STRUCTP macros
465 don't use strcpy and strlen (use safe_* equivalents)
466 reason: to avoid traps due to buffer overruns
468 don't use getopt_long, use popt functions instead
471 explicitly add const qualifiers on parm passing in functions where parm
472 is input only (somewhat controversial but const can be #defined away)
474 when passing a va_list as an arg, or assigning one to another
475 please use the VA_COPY() macro
476 reason: on some platforms, va_list is a struct that must be
477 initialized in each function...can SEGV if you don't.
479 discourage use of threads
480 reason: portability (also see architecture.doc)
482 don't explicitly include new header files in C files - new h files
483 should be included by adding them once to includes.h
486 don't explicitly extern functions (they are autogenerated by
487 "make proto
" into proto.h)
490 use endian safe macros when unpacking SMBs (see byteorder.h and
492 reason: not everyone uses Intel
494 Note Unicode implications of charset handling (see internals.doc). See
495 pull_* and push_* and convert_string functions.
496 reason: Internationalization
498 Don't assume English only
501 Try to avoid using in/out parameters (functions that return data which
502 overwrites input parameters)
503 reason: Can cause stability problems
505 Ensure copyright notices are correct, don't append Tridge's name to code
506 that he didn't write. If you did not write the code, make sure that it
507 can coexist with the rest of the Samba GPLed code.
509 Consider usage of DATA_BLOBs for length specified byte-data.
512 Take advantage of tdbs for database like function
515 Don't access the SAM_ACCOUNT structure directly, they should be accessed
516 via pdb_get...() and pdb_set...() functions.
517 reason: stability, consistency
519 Don't check a password directly against the passdb, always use the
520 check_password() interface.
521 reason: long term pluggability
523 Try to use asprintf rather than pstrings and fstrings where possible
525 Use normal C comments / * instead of C++ comments // like
526 this. Although the C++ comment format is part of the C99
527 standard, some older vendor C compilers do not accept it.
529 Try to write documentation for API functions and structures
530 explaining the point of the code, the way it should be used, and
531 any special conditions or results. Mark these with a double-star
532 comment start / ** so that they can be picked up by Doxygen, as in
535 Keep the scope narrow. This means making functions/variables
536 static whenever possible. We don't want our namespace
537 polluted. Each module should have a minimal number of externally
538 visible functions or variables.
540 Use function pointers to keep knowledge about particular pieces of
541 code isolated in one place. We don't want a particular piece of
542 functionality to be spread out across lots of places - that makes
543 for fragile, hand to maintain code. Instead, design an interface
544 and use tables containing function pointers to implement specific
545 functionality. This is particularly important for command
548 Think carefully about what it will be like for someone else to add
549 to and maintain your code. If it would be hard for someone else to
550 maintain then do it another way.
551 </p></li></ol></div><p>
552 The suggestions above are simply that, suggestions, but the information may
553 help in reducing the routine rework done on new code. The preceeding list
554 is expected to change routinely as new support routines and macros are
556 </p></div><div class=
"chapter" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title"><a name=
"internals"></a>Chapter
5. Samba Internals
</h2></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">David
</span> <span class=
"surname">Chappell
</span></h3><div class=
"affiliation"><div class=
"address"><p><tt class=
"email"><<a href=
"mailto:David.Chappell@mail.trincoll.edu">David.Chappell@mail.trincoll.edu
</a>></tt></p></div></div></div></div><div><p class=
"pubdate">8 May
1996</p></div></div><div></div></div><div class=
"toc"><p><b>Table of Contents
</b></p><dl><dt><a href=
"#id2866920">Character Handling
</a></dt><dt><a href=
"#id2866946">The new functions
</a></dt><dt><a href=
"#id2868198">Macros in byteorder.h
</a></dt><dd><dl><dt><a href=
"#id2869122">CVAL(buf,pos)
</a></dt><dt><a href=
"#id2869136">PVAL(buf,pos)
</a></dt><dt><a href=
"#id2869150">SCVAL(buf,pos,val)
</a></dt><dt><a href=
"#id2869163">SVAL(buf,pos)
</a></dt><dt><a href=
"#id2869179">IVAL(buf,pos)
</a></dt><dt><a href=
"#id2869193">SVALS(buf,pos)
</a></dt><dt><a href=
"#id2869208">IVALS(buf,pos)
</a></dt><dt><a href=
"#id2869222">SSVAL(buf,pos,val)
</a></dt><dt><a href=
"#id2869236">SIVAL(buf,pos,val)
</a></dt><dt><a href=
"#id2869251">SSVALS(buf,pos,val)
</a></dt><dt><a href=
"#id2869265">SIVALS(buf,pos,val)
</a></dt><dt><a href=
"#id2869280">RSVAL(buf,pos)
</a></dt><dt><a href=
"#id2869294">RIVAL(buf,pos)
</a></dt><dt><a href=
"#id2869308">RSSVAL(buf,pos,val)
</a></dt><dt><a href=
"#id2869323">RSIVAL(buf,pos,val)
</a></dt></dl></dd><dt><a href=
"#id2869339">LAN Manager Samba API
</a></dt><dd><dl><dt><a href=
"#id2869375">Parameters
</a></dt><dt><a href=
"#id2869526">Return value
</a></dt></dl></dd><dt><a href=
"#id2869611">Code character table
</a></dt></dl></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2866920"></a>Character Handling
</h2></div></div><div></div></div><p>
557 This section describes character set handling in Samba, as implemented in
560 In the past Samba had very ad-hoc character set handling. Scattered
561 throughout the code were numerous calls which converted particular
562 strings to/from DOS codepages. The problem is that there was no way of
563 telling if a particular char* is in dos codepage or unix
564 codepage. This led to a nightmare of code that tried to cope with
565 particular cases without handlingt the general case.
566 </p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2866946"></a>The new functions
</h2></div></div><div></div></div><p>
567 The new system works like this:
568 </p><div class=
"orderedlist"><ol type=
"1"><li><p>
569 all char* strings inside Samba are
"unix
" strings. These are
570 multi-byte strings that are in the charset defined by the
"unix
571 charset
" option in smb.conf.
573 there is no single fixed character set for unix strings, but any
574 character set that is used does need the following properties:
575 </p><div class=
"orderedlist"><ol type=
"a"><li><p>
576 must not contain NULLs except for termination
578 must be
7-bit compatible with C strings, so that a constant
579 string or character in C will be byte-for-byte identical to the
580 equivalent string in the chosen character set.
582 when you uppercase or lowercase a string it does not become
583 longer than the original string
585 must be able to correctly hold all characters that your client
587 </p></li></ol></div><p>
588 For example, UTF-
8 is fine, and most multi-byte asian character sets
589 are fine, but UCS2 could not be used for unix strings as they
592 when you need to put a string into a buffer that will be sent on the
593 wire, or you need a string in a character set format that is
594 compatible with the clients character set then you need to use a
595 pull_ or push_ function. The pull_ functions pull a string from a
596 wire buffer into a (multi-byte) unix string. The push_ functions
597 push a string out to a wire buffer.
599 the two main pull_ and push_ functions you need to understand are
600 pull_string and push_string. These functions take a base pointer
601 that should point at the start of the SMB packet that the string is
602 in. The functions will check the flags field in this packet to
603 automatically determine if the packet is marked as a unicode packet,
604 and they will choose whether to use unicode for this string based on
605 that flag. You may also force this decision using the STR_UNICODE or
606 STR_ASCII flags. For use in smbd/ and libsmb/ there are wrapper
607 functions clistr_ and srvstr_ that call the pull_/push_ functions
608 with the appropriate first argument.
610 You may also call the pull_ascii/pull_ucs2 or push_ascii/push_ucs2
611 functions if you know that a particular string is ascii or
612 unicode. There are also a number of other convenience functions in
613 charcnv.c that call the pull_/push_ functions with particularly
614 common arguments, such as pull_ascii_pstring()
616 The biggest thing to remember is that internal (unix) strings in Samba
617 may now contain multi-byte characters. This means you cannot assume
618 that characters are always
1 byte long. Often this means that you will
619 have to convert strings to ucs2 and back again in order to do some
620 (seemingly) simple task. For examples of how to do this see functions
621 like strchr_m(). I know this is very slow, and we will eventually
622 speed it up but right now we want this stuff correct not fast.
624 all lp_ functions now return unix strings. The magic
"DOS
" flag on
627 all vfs functions take unix strings. Don't convert when passing to them
628 </p></li></ol></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2868198"></a>Macros in byteorder.h
</h2></div></div><div></div></div><p>
629 This section describes the macros defined in byteorder.h. These macros
630 are used extensively in the Samba code.
631 </p><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2869122"></a>CVAL(buf,pos)
</h3></div></div><div></div></div><p>
632 returns the byte at offset pos within buffer buf as an unsigned character.
633 </p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2869136"></a>PVAL(buf,pos)
</h3></div></div><div></div></div><p>returns the value of CVAL(buf,pos) cast to type unsigned integer.
</p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2869150"></a>SCVAL(buf,pos,val)
</h3></div></div><div></div></div><p>sets the byte at offset pos within buffer buf to value val.
</p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2869163"></a>SVAL(buf,pos)
</h3></div></div><div></div></div><p>
634 returns the value of the unsigned short (
16 bit) little-endian integer at
635 offset pos within buffer buf. An integer of this type is sometimes
636 refered to as
"USHORT
".
637 </p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2869179"></a>IVAL(buf,pos)
</h3></div></div><div></div></div><p>returns the value of the unsigned
32 bit little-endian integer at offset
638 pos within buffer buf.
</p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2869193"></a>SVALS(buf,pos)
</h3></div></div><div></div></div><p>returns the value of the signed short (
16 bit) little-endian integer at
639 offset pos within buffer buf.
</p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2869208"></a>IVALS(buf,pos)
</h3></div></div><div></div></div><p>returns the value of the signed
32 bit little-endian integer at offset pos
640 within buffer buf.
</p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2869222"></a>SSVAL(buf,pos,val)
</h3></div></div><div></div></div><p>sets the unsigned short (
16 bit) little-endian integer at offset pos within
641 buffer buf to value val.
</p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2869236"></a>SIVAL(buf,pos,val)
</h3></div></div><div></div></div><p>sets the unsigned
32 bit little-endian integer at offset pos within buffer
642 buf to the value val.
</p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2869251"></a>SSVALS(buf,pos,val)
</h3></div></div><div></div></div><p>sets the short (
16 bit) signed little-endian integer at offset pos within
643 buffer buf to the value val.
</p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2869265"></a>SIVALS(buf,pos,val)
</h3></div></div><div></div></div><p>sets the signed
32 bit little-endian integer at offset pos withing buffer
644 buf to the value val.
</p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2869280"></a>RSVAL(buf,pos)
</h3></div></div><div></div></div><p>returns the value of the unsigned short (
16 bit) big-endian integer at
645 offset pos within buffer buf.
</p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2869294"></a>RIVAL(buf,pos)
</h3></div></div><div></div></div><p>returns the value of the unsigned
32 bit big-endian integer at offset
646 pos within buffer buf.
</p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2869308"></a>RSSVAL(buf,pos,val)
</h3></div></div><div></div></div><p>sets the value of the unsigned short (
16 bit) big-endian integer at
647 offset pos within buffer buf to value val.
648 refered to as
"USHORT
".
</p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2869323"></a>RSIVAL(buf,pos,val)
</h3></div></div><div></div></div><p>sets the value of the unsigned
32 bit big-endian integer at offset
649 pos within buffer buf to value val.
</p></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2869339"></a>LAN Manager Samba API
</h2></div></div><div></div></div><p>
650 This section describes the functions need to make a LAN Manager RPC call.
651 This information had been obtained by examining the Samba code and the LAN
652 Manager
2.0 API documentation. It should not be considered entirely
655 </p><pre class=
"programlisting">
656 call_api(int prcnt, int drcnt, int mprcnt, int mdrcnt,
657 char *param, char *data, char **rparam, char **rdata);
660 This function is defined in client.c. It uses an SMB transaction to call a
662 </p><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2869375"></a>Parameters
</h3></div></div><div></div></div><p>The parameters are as follows:
</p><div class=
"orderedlist"><ol type=
"1"><li><p>
663 prcnt: the number of bytes of parameters begin sent.
665 drcnt: the number of bytes of data begin sent.
667 mprcnt: the maximum number of bytes of parameters which should be returned
669 mdrcnt: the maximum number of bytes of data which should be returned
671 param: a pointer to the parameters to be sent.
673 data: a pointer to the data to be sent.
675 rparam: a pointer to a pointer which will be set to point to the returned
676 paramters. The caller of call_api() must deallocate this memory.
678 rdata: a pointer to a pointer which will be set to point to the returned
679 data. The caller of call_api() must deallocate this memory.
680 </p></li></ol></div><p>
681 These are the parameters which you ought to send, in the order of their
682 appearance in the parameter block:
683 </p><div class=
"orderedlist"><ol type=
"1"><li><p>
684 An unsigned
16 bit integer API number. You should set this value with
685 SSVAL(). I do not know where these numbers are described.
687 An ASCIIZ string describing the parameters to the API function as defined
688 in the LAN Manager documentation. The first parameter, which is the server
689 name, is ommited. This string is based uppon the API function as described
690 in the manual, not the data which is actually passed.
692 An ASCIIZ string describing the data structure which ought to be returned.
694 Any parameters which appear in the function call, as defined in the LAN
695 Manager API documentation, after the
"Server
" and up to and including the
696 "uLevel
" parameters.
698 An unsigned
16 bit integer which gives the size in bytes of the buffer we
699 will use to receive the returned array of data structures. Presumably this
700 should be the same as mdrcnt. This value should be set with SSVAL().
702 An ASCIIZ string describing substructures which should be returned. If no
703 substructures apply, this string is of zero length.
704 </p></li></ol></div><p>
705 The code in client.c always calls call_api() with no data. It is unclear
706 when a non-zero length data buffer would be sent.
707 </p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2869526"></a>Return value
</h3></div></div><div></div></div><p>
708 The returned parameters (pointed to by rparam), in their order of appearance
709 are:
</p><div class=
"orderedlist"><ol type=
"1"><li><p>
710 An unsigned
16 bit integer which contains the API function's return code.
711 This value should be read with SVAL().
713 An adjustment which tells the amount by which pointers in the returned
714 data should be adjusted. This value should be read with SVAL(). Basically,
715 the address of the start of the returned data buffer should have the returned
716 pointer value added to it and then have this value subtracted from it in
717 order to obtain the currect offset into the returned data buffer.
719 A count of the number of elements in the array of structures returned.
720 It is also possible that this may sometimes be the number of bytes returned.
721 </p></li></ol></div><p>
722 When call_api() returns, rparam points to the returned parameters. The
723 first if these is the result code. It will be zero if the API call
724 suceeded. This value by be read with
"SVAL(rparam,
0)
".
726 The second parameter may be read as
"SVAL(rparam,
2)
". It is a
16 bit offset
727 which indicates what the base address of the returned data buffer was when
728 it was built on the server. It should be used to correct pointer before
731 The returned data buffer contains the array of returned data structures.
732 Note that all pointers must be adjusted before use. The function
733 fix_char_ptr() in client.c can be used for this purpose.
735 The third parameter (which may be read as
"SVAL(rparam,
4)
") has something to
736 do with indicating the amount of data returned or possibly the amount of
737 data which can be returned if enough buffer space is allowed.
738 </p></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2869611"></a>Code character table
</h2></div></div><div></div></div><p>
739 Certain data structures are described by means of ASCIIz strings containing
740 code characters. These are the code characters:
741 </p><div class=
"orderedlist"><ol type=
"1"><li><p>
742 W a type byte little-endian unsigned integer
744 N a count of substructures which follow
746 D a four byte little-endian unsigned integer
748 B a byte (with optional count expressed as trailing ASCII digits)
750 z a four byte offset to a NULL terminated string
752 l a four byte offset to non-string user data
754 b an offset to data (with count expressed as trailing ASCII digits)
756 r pointer to returned data buffer???
758 L length in bytes of returned data buffer???
760 h number of bytes of information available???
761 </p></li></ol></div></div></div><div class=
"chapter" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title"><a name=
"parsing"></a>Chapter
6. The smb.conf file
</h2></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Chris
</span> <span class=
"surname">Hertel
</span></h3></div></div><div><p class=
"pubdate">November
1997</p></div></div><div></div></div><div class=
"toc"><p><b>Table of Contents
</b></p><dl><dt><a href=
"#id2868950">Lexical Analysis
</a></dt><dd><dl><dt><a href=
"#id2869043">Handling of Whitespace
</a></dt><dt><a href=
"#id2869099">Handling of Line Continuation
</a></dt><dt><a href=
"#id2870758">Line Continuation Quirks
</a></dt></dl></dd><dt><a href=
"#id2870856">Syntax
</a></dt><dd><dl><dt><a href=
"#id2870928">About params.c
</a></dt></dl></dd></dl></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2868950"></a>Lexical Analysis
</h2></div></div><div></div></div><p>
762 Basically, the file is processed on a line by line basis. There are
763 four types of lines that are recognized by the lexical analyzer
765 </p><div class=
"orderedlist"><ol type=
"1"><li><p>
766 Blank lines - Lines containing only whitespace.
768 Comment lines - Lines beginning with either a semi-colon or a
769 pound sign (';' or '#').
771 Section header lines - Lines beginning with an open square bracket ('[').
773 Parameter lines - Lines beginning with any other character.
774 (The default line type.)
775 </p></li></ol></div><p>
776 The first two are handled exclusively by the lexical analyzer, which
777 ignores them. The latter two line types are scanned for
778 </p><div class=
"orderedlist"><ol type=
"1"><li><p>
784 </p></li></ol></div><p>
785 These are the only tokens passed to the parameter loader
786 (loadparm.c). Parameter names and values are divided from one
787 another by an equal sign: '='.
788 </p><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2869043"></a>Handling of Whitespace
</h3></div></div><div></div></div><p>
789 Whitespace is defined as all characters recognized by the isspace()
790 function (see ctype(
3C)) except for the newline character ('\n')
791 The newline is excluded because it identifies the end of the line.
792 </p><div class=
"orderedlist"><ol type=
"1"><li><p>
793 The lexical analyzer scans past white space at the beginning of a line.
795 Section and parameter names may contain internal white space. All
796 whitespace within a name is compressed to a single space character.
798 Internal whitespace within a parameter value is kept verbatim with
799 the exception of carriage return characters ('\r'), all of which
802 Leading and trailing whitespace is removed from names and values.
803 </p></li></ol></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2869099"></a>Handling of Line Continuation
</h3></div></div><div></div></div><p>
804 Long section header and parameter lines may be extended across
805 multiple lines by use of the backslash character ('\\'). Line
806 continuation is ignored for blank and comment lines.
808 If the last (non-whitespace) character within a section header or on
809 a parameter line is a backslash, then the next line will be
810 (logically) concatonated with the current line by the lexical
811 analyzer. For example:
812 </p><pre class=
"programlisting">
813 param name = parameter value string \
814 with line continuation.
815 </pre><p>Would be read as
</p><pre class=
"programlisting">
816 param name = parameter value string with line continuation.
818 Note that there are five spaces following the word 'string',
819 representing the one space between 'string' and '\\' in the top
820 line, plus the four preceeding the word 'with' in the second line.
821 (Yes, I'm counting the indentation.)
823 Line continuation characters are ignored on blank lines and at the end
824 of comments. They are *only* recognized within section and parameter
826 </p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2870758"></a>Line Continuation Quirks
</h3></div></div><div></div></div><p>Note the following example:
</p><pre class=
"programlisting">
827 param name = parameter value string \
829 with line continuation.
831 The middle line is *not* parsed as a blank line because it is first
832 concatonated with the top line. The result is
833 </p><pre class=
"programlisting">
834 param name = parameter value string with line continuation.
835 </pre><p>The same is true for comment lines.
</p><pre class=
"programlisting">
836 param name = parameter value string \
839 </pre><p>This becomes:
</p><pre class=
"programlisting">
840 param name = parameter value string ; comment with a comment.
842 On a section header line, the closing bracket (']') is considered a
843 terminating character, and the rest of the line is ignored. The lines
844 </p><pre class=
"programlisting">
845 [ section name ] garbage \
847 </pre><p>are read as
</p><pre class=
"programlisting">
850 </pre></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2870856"></a>Syntax
</h2></div></div><div></div></div><p>The syntax of the smb.conf file is as follows:
</p><pre class=
"programlisting">
851 <file
> :== {
<section
> } EOF
852 <section
> :==
<section header
> {
<parameter line
> }
853 <section header
> :== '[' NAME ']'
854 <parameter line
> :== NAME '=' VALUE NL
855 </pre><p>Basically, this means that
</p><div class=
"orderedlist"><ol type=
"1"><li><p>
856 a file is made up of zero or more sections, and is terminated by
857 an EOF (we knew that).
859 A section is made up of a section header followed by zero or more
862 A section header is identified by an opening bracket and
863 terminated by the closing bracket. The enclosed NAME identifies
866 A parameter line is divided into a NAME and a VALUE. The *first*
867 equal sign on the line separates the NAME from the VALUE. The
868 VALUE is terminated by a newline character (NL = '\n').
869 </p></li></ol></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2870928"></a>About params.c
</h3></div></div><div></div></div><p>
870 The parsing of the config file is a bit unusual if you are used to
871 lex, yacc, bison, etc. Both lexical analysis (scanning) and parsing
872 are performed by params.c. Values are loaded via callbacks to
874 </p></div></div></div><div class=
"chapter" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title"><a name=
"unix-smb"></a>Chapter
7. NetBIOS in a Unix World
</h2></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Andrew
</span> <span class=
"surname">Tridgell
</span></h3></div></div><div><p class=
"pubdate">April
1995</p></div></div><div></div></div><div class=
"toc"><p><b>Table of Contents
</b></p><dl><dt><a href=
"#id2870375">Introduction
</a></dt><dt><a href=
"#id2870400">Usernames
</a></dt><dt><a href=
"#id2870628">File Ownership
</a></dt><dt><a href=
"#id2870665">Passwords
</a></dt><dt><a href=
"#id2870702">Locking
</a></dt><dt><a href=
"#id2871641">Deny Modes
</a></dt><dt><a href=
"#id2871672">Trapdoor UIDs
</a></dt><dt><a href=
"#id2871697">Port numbers
</a></dt><dt><a href=
"#id2871742">Protocol Complexity
</a></dt></dl></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2870375"></a>Introduction
</h2></div></div><div></div></div><p>
875 This is a short document that describes some of the issues that
876 confront a SMB implementation on unix, and how Samba copes with
877 them. They may help people who are looking at unix
<-
>PC
880 It was written to help out a person who was writing a paper on unix to
882 </p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2870400"></a>Usernames
</h2></div></div><div></div></div><p>
883 The SMB protocol has only a loose username concept. Early SMB
884 protocols (such as CORE and COREPLUS) have no username concept at
885 all. Even in later protocols clients often attempt operations
886 (particularly printer operations) without first validating a username
889 Unix security is based around username/password pairs. A unix box
890 should not allow clients to do any substantive operation without some
893 The problem mostly manifests itself when the unix server is in
"share
894 level
" security mode. This is the default mode as the alternative
895 "user level
" security mode usually forces a client to connect to the
896 server as the same user for each connected share, which is
897 inconvenient in many sites.
899 In
"share level
" security the client normally gives a username in the
900 "session setup
" protocol, but does not supply an accompanying
901 password. The client then connects to resources using the
"tree
902 connect
" protocol, and supplies a password. The problem is that the
903 user on the PC types the username and the password in different
904 contexts, unaware that they need to go together to give access to the
905 server. The username is normally the one the user typed in when they
906 "logged onto
" the PC (this assumes Windows for Workgroups). The
907 password is the one they chose when connecting to the disk or printer.
909 The user often chooses a totally different username for their login as
910 for the drive connection. Often they also want to access different
911 drives as different usernames. The unix server needs some way of
912 divining the correct username to combine with each password.
914 Samba tries to avoid this problem using several methods. These succeed
915 in the vast majority of cases. The methods include username maps, the
916 service%user syntax, the saving of session setup usernames for later
917 validation and the derivation of the username from the service name
918 (either directly or via the user= option).
919 </p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2870628"></a>File Ownership
</h2></div></div><div></div></div><p>
920 The commonly used SMB protocols have no way of saying
"you can't do
921 that because you don't own the file
". They have, in fact, no concept
922 of file ownership at all.
924 This brings up all sorts of interesting problems. For example, when
925 you copy a file to a unix drive, and the file is world writeable but
926 owned by another user the file will transfer correctly but will
927 receive the wrong date. This is because the utime() call under unix
928 only succeeds for the owner of the file, or root, even if the file is
929 world writeable. For security reasons Samba does all file operations
930 as the validated user, not root, so the utime() fails. This can stuff
931 up shared development diectories as programs like
"make
" will not get
932 file time comparisons right.
934 There are several possible solutions to this problem, including
935 username mapping, and forcing a specific username for particular
937 </p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2870665"></a>Passwords
</h2></div></div><div></div></div><p>
938 Many SMB clients uppercase passwords before sending them. I have no
939 idea why they do this. Interestingly WfWg uppercases the password only
940 if the server is running a protocol greater than COREPLUS, so
941 obviously it isn't just the data entry routines that are to blame.
943 Unix passwords are case sensitive. So if users use mixed case
944 passwords they are in trouble.
946 Samba can try to cope with this by either using the
"password level
"
947 option which causes Samba to try the offered password with up to the
948 specified number of case changes, or by using the
"password server
"
949 option which allows Samba to do its validation via another machine
950 (typically a WinNT server).
952 Samba supports the password encryption method used by SMB
953 clients. Note that the use of password encryption in Microsoft
954 networking leads to password hashes that are
"plain text equivalent
".
955 This means that it is *VERY* important to ensure that the Samba
956 smbpasswd file containing these password hashes is only readable
957 by the root user. See the documentation ENCRYPTION.txt for more
959 </p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2870702"></a>Locking
</h2></div></div><div></div></div><p>
960 Since samba
2.2, samba supports other types of locking as well. This
963 The locking calls available under a DOS/Windows environment are much
964 richer than those available in unix. This means a unix server (like
965 Samba) choosing to use the standard fcntl() based unix locking calls
966 to implement SMB locking has to improvise a bit.
968 One major problem is that dos locks can be in a
32 bit (unsigned)
969 range. Unix locking calls are
32 bits, but are signed, giving only a
31
970 bit range. Unfortunately OLE2 clients use the top bit to select a
971 locking range used for OLE semaphores.
973 To work around this problem Samba compresses the
32 bit range into
31
974 bits by appropriate bit shifting. This seems to work but is not
975 ideal. In a future version a separate SMB lockd may be added to cope
978 It also doesn't help that many unix lockd daemons are very buggy and
979 crash at the slightest provocation. They normally go mostly unused in
980 a unix environment because few unix programs use byte range
981 locking. The stress of huge numbers of lock requests from dos/windows
982 clients can kill the daemon on some systems.
984 The second major problem is the
"opportunistic locking
" requested by
985 some clients. If a client requests opportunistic locking then it is
986 asking the server to notify it if anyone else tries to do something on
987 the same file, at which time the client will say if it is willing to
988 give up its lock. Unix has no simple way of implementing
989 opportunistic locking, and currently Samba has no support for it.
990 </p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2871641"></a>Deny Modes
</h2></div></div><div></div></div><p>
991 When a SMB client opens a file it asks for a particular
"deny mode
" to
992 be placed on the file. These modes (DENY_NONE, DENY_READ, DENY_WRITE,
993 DENY_ALL, DENY_FCB and DENY_DOS) specify what actions should be
994 allowed by anyone else who tries to use the file at the same time. If
995 DENY_READ is placed on the file, for example, then any attempt to open
996 the file for reading should fail.
998 Unix has no equivalent notion. To implement this Samba uses either lock
999 files based on the files inode and placed in a separate lock
1000 directory or a shared memory implementation. The lock file method
1001 is clumsy and consumes processing and file resources,
1002 the shared memory implementation is vastly prefered and is turned on
1003 by default for those systems that support it.
1004 </p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2871672"></a>Trapdoor UIDs
</h2></div></div><div></div></div><p>
1005 A SMB session can run with several uids on the one socket. This
1006 happens when a user connects to two shares with different
1007 usernames. To cope with this the unix server needs to switch uids
1008 within the one process. On some unixes (such as SCO) this is not
1009 possible. This means that on those unixes the client is restricted to
1012 Note that you can also get the
"trapdoor uid
" message for other
1013 reasons. Please see the FAQ for details.
1014 </p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2871697"></a>Port numbers
</h2></div></div><div></div></div><p>
1015 There is a convention that clients on sockets use high
"unprivilaged
"
1016 port numbers (
>1000) and connect to servers on low
"privilaged
" port
1017 numbers. This is enforced in Unix as non-root users can't open a
1018 socket for listening on port numbers less than
1000.
1020 Most PC based SMB clients (such as WfWg and WinNT) don't follow this
1021 convention completely. The main culprit is the netbios nameserving on
1022 udp port
137. Name query requests come from a source port of
137. This
1023 is a problem when you combine it with the common firewalling technique
1024 of not allowing incoming packets on low port numbers. This means that
1025 these clients can't query a netbios nameserver on the other side of a
1026 low port based firewall.
1028 The problem is more severe with netbios node status queries. I've
1029 found that WfWg, Win95 and WinNT3.5 all respond to netbios node status
1030 queries on port
137 no matter what the source port was in the
1031 request. This works between machines that are both using port
137, but
1032 it means it's not possible for a unix user to do a node status request
1033 to any of these OSes unless they are running as root. The answer comes
1034 back, but it goes to port
137 which the unix user can't listen
1035 on. Interestingly WinNT3.1 got this right - it sends node status
1036 responses back to the source port in the request.
1037 </p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2871742"></a>Protocol Complexity
</h2></div></div><div></div></div><p>
1038 There are many
"protocol levels
" in the SMB protocol. It seems that
1039 each time new functionality was added to a Microsoft operating system,
1040 they added the equivalent functions in a new protocol level of the SMB
1041 protocol to
"externalise
" the new capabilities.
1043 This means the protocol is very
"rich
", offering many ways of doing
1044 each file operation. This means SMB servers need to be complex and
1045 large. It also means it is very difficult to make them bug free. It is
1046 not just Samba that suffers from this problem, other servers such as
1047 WinNT don't support every variation of every call and it has almost
1048 certainly been a headache for MS developers to support the myriad of
1049 SMB calls that are available.
1051 There are about
65 "top level
" operations in the SMB protocol (things
1052 like SMBread and SMBwrite). Some of these include hundreds of
1053 sub-functions (SMBtrans has at least
120 sub-functions, like
1054 DosPrintQAdd and NetSessionEnum). All of them take several options
1055 that can change the way they work. Many take dozens of possible
1056 "information levels
" that change the structures that need to be
1057 returned. Samba supports all but
2 of the
"top level
" functions. It
1058 supports only
8 (so far) of the SMBtrans sub-functions. Even NT
1059 doesn't support them all.
1061 Samba currently supports up to the
"NT LM
0.12" protocol, which is the
1062 one preferred by Win95 and WinNT3.5. Luckily this protocol level has a
1063 "capabilities
" field which specifies which super-duper new-fangled
1064 options the server suports. This helps to make the implementation of
1065 this protocol level much easier.
1067 There is also a problem with the SMB specications. SMB is a X/Open
1068 spec, but the X/Open book is far from ideal, and fails to cover many
1069 important issues, leaving much to the imagination. Microsoft recently
1070 renamed the SMB protocol CIFS (Common Internet File System) and have
1071 published new specifications. These are far superior to the old
1072 X/Open documents but there are still undocumented calls and features.
1073 This specification is actively being worked on by a CIFS developers
1074 mailing list hosted by Microsft.
1075 </p></div></div><div class=
"chapter" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title"><a name=
"tracing"></a>Chapter
8. Tracing samba system calls
</h2></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Andrew
</span> <span class=
"surname">Tridgell
</span></h3><div class=
"affiliation"><span class=
"orgname">Samba Team
<br></span></div></div></div></div><div></div></div><p>
1076 This file describes how to do a system call trace on Samba to work out
1077 what its doing wrong. This is not for the faint of heart, but if you
1078 are reading this then you are probably desperate.
1080 Actually its not as bad as the the above makes it sound, just don't
1081 expect the output to be very pretty :-)
1083 Ok, down to business. One of the big advantages of unix systems is
1084 that they nearly all come with a system trace utility that allows you
1085 to monitor all system calls that a program is making. This is
1086 extremely using for debugging and also helps when trying to work out
1087 why something is slower than you expect. You can use system tracing
1088 without any special compilation options.
1090 The system trace utility is called different things on different
1091 systems. On Linux systems its called strace. Under SunOS
4 its called
1092 trace. Under SVR4 style systems (including solaris) its called
1093 truss. Under many BSD systems its called ktrace.
1095 The first thing you should do is read the man page for your native
1096 system call tracer. In the discussion below I'll assume its called
1097 strace as strace is the only portable system tracer (its available for
1098 free for many unix types) and its also got some of the nicest
1101 Next, try using strace on some simple commands. For example,
<b class=
"command">strace
1102 ls
</b> or
<b class=
"command">strace echo hello
</b>.
1104 You'll notice that it produces a LOT of output. It is showing you the
1105 arguments to every system call that the program makes and the
1106 result. Very little happens in a program without a system call so you
1107 get lots of output. You'll also find that it produces a lot of
1108 "preamble
" stuff showing the loading of shared libraries etc. Ignore
1109 this (unless its going wrong!)
1111 For example, the only line that really matters in the
<b class=
"command">strace echo
1112 hello
</b> output is:
1113 </p><pre class=
"programlisting">
1114 write(
1,
"hello\n
",
6) =
6
1115 </pre><p>all the rest is just setting up to run the program.
</p><p>
1116 Ok, now you're familiar with strace. To use it on Samba you need to
1117 strace the running smbd daemon. The way I tend ot use it is to first
1118 login from my Windows PC to the Samba server, then use smbstatus to
1119 find which process ID that client is attached to, then as root I do
1120 <b class=
"command">strace -p PID
</b> to attach to that process. I normally redirect the
1121 stderr output from this command to a file for later perusal. For
1122 example, if I'm using a csh style shell:
1123 </p><p><b class=
"command">strace -f -p
3872 >& strace.out
</b></p><p>or with a sh style shell:
</p><p><b class=
"command">strace -f -p
3872 > strace.out
2>&1</b></p><p>
1124 Note the
"-f
" option. This is only available on some systems, and
1125 allows you to trace not just the current process, but any children it
1126 forks. This is great for finding printing problems caused by the
1127 "print command
" being wrong.
1129 Once you are attached you then can do whatever it is on the client
1130 that is causing problems and you will capture all the system calls
1133 So how do you interpret the results? Generally I search through the
1134 output for strings that I know will appear when the problem
1135 happens. For example, if I am having touble with permissions on a file
1136 I would search for that files name in the strace output and look at
1137 the surrounding lines. Another trick is to match up file descriptor
1138 numbers and
"follow
" what happens to an open file until it is closed.
1140 Beyond this you will have to use your initiative. To give you an idea
1141 of what you are looking for here is a piece of strace output that
1142 shows that
<tt class=
"filename">/dev/null
</tt> is not world writeable, which
1143 causes printing to fail with Samba:
1144 </p><pre class=
"programlisting">
1145 [pid
28268] open(
"/dev/null
", O_RDWR) = -
1 EACCES (Permission denied)
1146 [pid
28268] open(
"/dev/null
", O_WRONLY) = -
1 EACCES (Permission denied)
1148 The process is trying to first open
<tt class=
"filename">/dev/null
</tt> read-write
1149 then read-only. Both fail. This means
<tt class=
"filename">/dev/null
</tt> has
1150 incorrect permissions.
1151 </p></div><div class=
"chapter" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title"><a name=
"windows-debug"></a>Chapter
9. Finding useful information on windows
</h2></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Jelmer
</span> <span class=
"othername">R.
</span> <span class=
"surname">Vernooij
</span></h3><div class=
"affiliation"><span class=
"orgname">The Samba Team
<br></span><div class=
"address"><p><tt class=
"email"><<a href=
"mailto:jelmer@samba.org">jelmer@samba.org
</a>></tt></p></div></div></div></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Andrew
</span> <span class=
"surname">Tridgell
</span></h3><div class=
"affiliation"><span class=
"orgname">Samba Team
<br></span><div class=
"address"><p><tt class=
"email"><<a href=
"mailto:tridge@samba.org">tridge@samba.org
</a>></tt></p></div></div></div></div></div><div></div></div><div class=
"toc"><p><b>Table of Contents
</b></p><dl><dt><a href=
"#id2871397">Netlogon debugging output
</a></dt></dl></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2871397"></a>Netlogon debugging output
</h2></div></div><div></div></div><div class=
"procedure"><ol type=
"1"><li><p>stop netlogon service on PDC
</p></li><li><p>rename original netlogon.dll to netlogon.dll.original
</p></li><li><p>copy checked version of netlogon.dll to system32 directory
</p></li><li><p>set HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters\DBFlag to
0x20000004</p></li><li><p>start netlogon service on PDC
</p></li></ol></div></div></div><div class=
"chapter" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title"><a name=
"ntdomain"></a>Chapter
10. NT Domain RPC's
</h2></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Luke
</span> <span class=
"surname">Leighton
</span></h3><div class=
"affiliation"><div class=
"address"><p><tt class=
"email"><<a href=
"mailto:lkcl@switchboard.net">lkcl@switchboard.net
</a>></tt></p></div></div></div></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Paul
</span> <span class=
"surname">Ashton
</span></h3><div class=
"affiliation"><div class=
"address"><p><tt class=
"email"><<a href=
"mailto:paul@argo.demon.co.uk">paul@argo.demon.co.uk
</a>></tt></p></div></div></div></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Duncan
</span> <span class=
"surname">Stansfield
</span></h3><div class=
"affiliation"><div class=
"address"><p><tt class=
"email"><<a href=
"mailto:duncans@sco.com">duncans@sco.com
</a>></tt></p></div></div></div></div><div><p class=
"pubdate">01 November
97(version
0.0.24)
</p></div></div><div></div></div><div class=
"toc"><p><b>Table of Contents
</b></p><dl><dt><a href=
"#id2872364">Introduction
</a></dt><dd><dl><dt><a href=
"#id2873295">Sources
</a></dt><dt><a href=
"#id2873330">Credits
</a></dt></dl></dd><dt><a href=
"#id2873367">Notes and Structures
</a></dt><dd><dl><dt><a href=
"#id2873375">Notes
</a></dt><dt><a href=
"#id2873451">Enumerations
</a></dt><dt><a href=
"#id2873665">Structures
</a></dt></dl></dd><dt><a href=
"#id2876614">MSRPC over Transact Named Pipe
</a></dt><dd><dl><dt><a href=
"#id2876627">MSRPC Pipes
</a></dt><dt><a href=
"#id2876729">Header
</a></dt><dt><a href=
"#id2877600">Tail
</a></dt><dt><a href=
"#id2877647">RPC Bind / Bind Ack
</a></dt><dt><a href=
"#id2877826">NTLSA Transact Named Pipe
</a></dt><dt><a href=
"#id2877991">LSA Open Policy
</a></dt><dt><a href=
"#id2878118">LSA Query Info Policy
</a></dt><dt><a href=
"#id2878223">LSA Enumerate Trusted Domains
</a></dt><dt><a href=
"#id2878315">LSA Open Secret
</a></dt><dt><a href=
"#id2878424">LSA Close
</a></dt><dt><a href=
"#id2878490">LSA Lookup SIDS
</a></dt><dt><a href=
"#id2878700">LSA Lookup Names
</a></dt></dl></dd><dt><a href=
"#id2878926">NETLOGON rpc Transact Named Pipe
</a></dt><dd><dl><dt><a href=
"#id2879087">LSA Request Challenge
</a></dt><dt><a href=
"#id2879222">LSA Authenticate
2</a></dt><dt><a href=
"#id2879369">LSA Server Password Set
</a></dt><dt><a href=
"#id2879484">LSA SAM Logon
</a></dt><dt><a href=
"#id2879598">LSA SAM Logoff
</a></dt></dl></dd><dt><a href=
"#id2879689">\\MAILSLOT\NET\NTLOGON
</a></dt><dd><dl><dt><a href=
"#id2879701">Query for PDC
</a></dt><dt><a href=
"#id2879969">SAM Logon
</a></dt></dl></dd><dt><a href=
"#id2880294">SRVSVC Transact Named Pipe
</a></dt><dd><dl><dt><a href=
"#id2880339">Net Share Enum
</a></dt><dt><a href=
"#id2880558">Net Server Get Info
</a></dt></dl></dd><dt><a href=
"#id2880674">Cryptographic side of NT Domain Authentication
</a></dt><dd><dl><dt><a href=
"#id2880682">Definitions
</a></dt><dt><a href=
"#id2880845">Protocol
</a></dt><dt><a href=
"#id2880942">Comments
</a></dt></dl></dd><dt><a href=
"#id2880991">SIDs and RIDs
</a></dt><dd><dl><dt><a href=
"#id2881031">Well-known SIDs
</a></dt><dt><a href=
"#id2881346">Well-known RIDS
</a></dt></dl></dd></dl></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2872364"></a>Introduction
</h2></div></div><div></div></div><p>
1152 This document contains information to provide an NT workstation with login
1153 services, without the need for an NT server. It is the sgml version of
<a href=
"http://mailhost.cb1.com/~lkcl/cifsntdomain.txt" target=
"_top">http://mailhost.cb1.com/~lkcl/cifsntdomain.txt
</a>, controlled by Luke.
1155 It should be possible to select a domain instead of a workgroup (in the NT
1156 workstation's TCP/IP settings) and after the obligatory reboot, type in a
1157 username, password, select a domain and successfully log in. I would
1158 appreciate any feedback on your experiences with this process, and any
1159 comments, corrections and additions to this document.
1161 The packets described here can be easily derived from (and are probably
1162 better understood using) Netmon.exe. You will need to use the version
1163 of Netmon that matches your system, in order to correctly decode the
1164 NETLOGON, lsarpc and srvsvc Transact pipes. This document is derived from
1165 NT Service Pack
1 and its corresponding version of Netmon. It is intended
1166 that an annotated packet trace be produced, which will likely be more
1167 instructive than this document.
1169 Also needed, to fully implement NT Domain Login Services, is the
1170 document describing the cryptographic part of the NT authentication.
1171 This document is available from comp.protocols.smb; from the ntsecurity.net
1172 digest and from the samba digest, amongst other sources.
1174 A copy is available from:
1175 </p><p><a href=
"http://ntbugtraq.rc.on.ca/SCRIPTS/WA.EXE?A2=ind9708;L=ntbugtraq;O=A;P=2935" target=
"_top">http://ntbugtraq.rc.on.ca/SCRIPTS/WA.EXE?A2=ind9708;L=ntbugtraq;O=A;P=
2935</a></p><p><a href=
"http://mailhost.cb1.com/~lkcl/crypt.html" target=
"_top">http://mailhost.cb1.com/~lkcl/crypt.html
</a></p><p>
1176 A c-code implementation, provided by
<a href=
"mailto:linus@incolumitas.se" target=
"_top">Linus Nordberg
</a>
1177 of this protocol is available from:
1178 </p><p><a href=
"http://samba.org/cgi-bin/mfs/01/digest/1997/97aug/0391.html" target=
"_top">http://samba.org/cgi-bin/mfs/
01/digest/
1997/
97aug/
0391.html
</a></p><p><a href=
"http://mailhost.cb1.com/~lkcl/crypt.txt" target=
"_top">http://mailhost.cb1.com/~lkcl/crypt.txt
</a></p><p>
1179 Also used to provide debugging information is the Check Build version of
1180 NT workstation, and enabling full debugging in NETLOGON. This is
1181 achieved by setting the following REG_SZ registry key to
0x1ffffff:
1182 </p><p><tt class=
"filename">HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters
</tt></p><p><span class=
"emphasis"><em>Incorrect direct editing of the registry can cause your
1183 machine to fail. Then again, so can incorrect implementation of this
1184 protocol. See
"Liability:
" above.
</em></span></p><p>
1185 Bear in mind that each packet over-the-wire will have its origin in an
1186 API call. Therefore, there are likely to be structures, enumerations
1187 and defines that are usefully documented elsewhere.
1189 This document is by no means complete or authoritative. Missing sections
1190 include, but are not limited to:
1191 </p><div class=
"orderedlist"><ol type=
"1"><li><p>Mappings of RIDs to usernames (and vice-versa).
</p></li><li><p>What a User ID is and what a Group ID is.
</p></li><li><p>The exact meaning/definition of various magic constants or enumerations.
</p></li><li><p>The reply error code and use of that error code when a
1192 workstation becomes a member of a domain (to be described later).
1193 Failure to return this error code will make the workstation report
1194 that it is already a member of the domain.
</p></li><li><p>the cryptographic side of the NetrServerPasswordSet command,
1195 which would allow the workstation to change its password. This password is
1196 used to generate the long-term session key. [It is possible to reject this
1197 command, and keep the default workstation password].
</p></li></ol></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2873295"></a>Sources
</h3></div></div><div></div></div><table class=
"simplelist" border=
"0" summary=
"Simple list"><tr><td>cket Traces from Netmonitor (Service Pack
1 and above)
</td></tr><tr><td>ul Ashton and Luke Leighton's other
"NT Domain
" doc.
</td></tr><tr><td>FS documentation - cifs6.txt
</td></tr><tr><td>FS documentation - cifsrap2.txt
</td></tr></table></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2873330"></a>Credits
</h3></div></div><div></div></div><table class=
"simplelist" border=
"0" summary=
"Simple list"><tr><td>Paul Ashton: loads of work with Net Monitor; understanding the NT authentication system; reference implementation of the NT domain support on which this document is originally based.
</td></tr><tr><td>Duncan Stansfield: low-level analysis of MSRPC Pipes.
</td></tr><tr><td>Linus Nordberg: producing c-code from Paul's crypto spec.
</td></tr><tr><td>Windows Sourcer development team
</td></tr></table></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2873367"></a>Notes and Structures
</h2></div></div><div></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2873375"></a>Notes
</h3></div></div><div></div></div><div class=
"orderedlist"><ol type=
"1"><li><p>
1198 In the SMB Transact pipes, some
"Structures
", described here, appear to be
1199 4-byte aligned with the SMB header, at their start. Exactly which
1200 "Structures
" need aligning is not precisely known or documented.
1202 In the UDP NTLOGON Mailslots, some
"Structures
", described here, appear to be
1203 2-byte aligned with the start of the mailslot, at their start.
1205 Domain SID is of the format S-revision-version-auth1-auth2...authN.
1206 e.g S-
1-
5-
123-
456-
789-
123-
456. the
5 could be a sub-revision.
1208 any undocumented buffer pointers must be non-zero if the string buffer it
1209 refers to contains characters. exactly what value they should be is unknown.
1210 0x0000 0002 seems to do the trick to indicate that the buffer exists. a
1211 NULL buffer pointer indicates that the string buffer is of zero length.
1212 If the buffer pointer is NULL, then it is suspected that the structure it
1213 refers to is NOT put into (or taken out of) the SMB data stream. This is
1214 empirically derived from, for example, the LSA SAM Logon response packet,
1215 where if the buffer pointer is NULL, the user information is not inserted
1216 into the data stream. Exactly what happens with an array of buffer pointers
1217 is not known, although an educated guess can be made.
1219 an array of structures (a container) appears to have a count and a pointer.
1220 if the count is zero, the pointer is also zero. no further data is put
1221 into or taken out of the SMB data stream. if the count is non-zero, then
1222 the pointer is also non-zero. immediately following the pointer is the
1223 count again, followed by an array of container sub-structures. the count
1224 appears a third time after the last sub-structure.
1225 </p></li></ol></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2873451"></a>Enumerations
</h3></div></div><div></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2873459"></a>MSRPC Header type
</h4></div></div><div></div></div><p>command number in the msrpc packet header
</p><div class=
"variablelist"><dl><dt><span class=
"term">MSRPC_Request:
</span></dt><dd><p>0x00</p></dd><dt><span class=
"term">MSRPC_Response:
</span></dt><dd><p>0x02</p></dd><dt><span class=
"term">MSRPC_Bind:
</span></dt><dd><p>0x0B</p></dd><dt><span class=
"term">MSRPC_BindAck:
</span></dt><dd><p>0x0C</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2873534"></a>MSRPC Packet info
</h4></div></div><div></div></div><p>The meaning of these flags is undocumented
</p><div class=
"variablelist"><dl><dt><span class=
"term">FirstFrag:
</span></dt><dd><p>0x01 </p></dd><dt><span class=
"term">LastFrag:
</span></dt><dd><p>0x02 </p></dd><dt><span class=
"term">NotaFrag:
</span></dt><dd><p>0x04 </p></dd><dt><span class=
"term">RecRespond:
</span></dt><dd><p>0x08 </p></dd><dt><span class=
"term">NoMultiplex:
</span></dt><dd><p>0x10 </p></dd><dt><span class=
"term">NotForIdemp:
</span></dt><dd><p>0x20 </p></dd><dt><span class=
"term">NotforBcast:
</span></dt><dd><p>0x40 </p></dd><dt><span class=
"term">NoUuid:
</span></dt><dd><p>0x80 </p></dd></dl></div></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2873665"></a>Structures
</h3></div></div><div></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2873672"></a>VOID *
</h4></div></div><div></div></div><p>sizeof VOID* is
32 bits.
</p></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2873683"></a>char
</h4></div></div><div></div></div><p>sizeof char is
8 bits.
</p></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2873695"></a>UTIME
</h4></div></div><div></div></div><p>UTIME is
32 bits, indicating time in seconds since
01jan1970. documented in cifs6.txt (section
3.5 page, page
30).
</p></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2873708"></a>NTTIME
</h4></div></div><div></div></div><p>NTTIME is
64 bits. documented in cifs6.txt (section
3.5 page, page
30).
</p></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2873720"></a>DOM_SID (domain SID structure)
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT32
</span></dt><dd><p>num of sub-authorities in domain SID
</p></dd><dt><span class=
"term">UINT8
</span></dt><dd><p>SID revision number
</p></dd><dt><span class=
"term">UINT8
</span></dt><dd><p>num of sub-authorities in domain SID
</p></dd><dt><span class=
"term">UINT8[
6]
</span></dt><dd><p>6 bytes for domain SID - Identifier Authority.
</p></dd><dt><span class=
"term">UINT16[n_subauths]
</span></dt><dd><p>domain SID sub-authorities
</p></dd></dl></div><p><span class=
"emphasis"><em>Note: the domain SID is documented elsewhere.
</em></span>
1226 </p></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2873813"></a>STR (string)
</h4></div></div><div></div></div><p>STR (string) is a char[] : a null-terminated string of ascii characters.
</p></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2873827"></a>UNIHDR (unicode string header)
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT16
</span></dt><dd><p>length of unicode string
</p></dd><dt><span class=
"term">UINT16
</span></dt><dd><p>max length of unicode string
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>4 - undocumented.
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2873883"></a>UNIHDR2 (unicode string header plus buffer pointer)
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UNIHDR
</span></dt><dd><p>unicode string header
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>undocumented buffer pointer
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2873925"></a>UNISTR (unicode string)
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT16[]
</span></dt><dd><p>null-terminated string of unicode characters.
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2873953"></a>NAME (length-indicated unicode string)
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT32
</span></dt><dd><p>length of unicode string
</p></dd><dt><span class=
"term">UINT16[]
</span></dt><dd><p>null-terminated string of unicode characters.
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2873995"></a>UNISTR2 (aligned unicode string)
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT8[]
</span></dt><dd><p>padding to get unicode string
4-byte aligned with the start of the SMB header.
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>max length of unicode string
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>0 - undocumented
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>length of unicode string
</p></dd><dt><span class=
"term">UINT16[]
</span></dt><dd><p>string of uncode characters
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2874081"></a>OBJ_ATTR (object attributes)
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT32
</span></dt><dd><p>0x18 - length (in bytes) including the length field.
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>0 - root directory (pointer)
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>0 - object name (pointer)
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>0 - attributes (undocumented)
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>0 - security descriptior (pointer)
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>0 - security quality of service
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2874174"></a>POL_HND (LSA policy handle)
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">char[
20]
</span></dt><dd><p>policy handle
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2874201"></a>DOM_SID2 (domain SID structure, SIDS stored in unicode)
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT32
</span></dt><dd><p>5 - SID type
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>0 - undocumented
</p></dd><dt><span class=
"term">UNIHDR2
</span></dt><dd><p>domain SID unicode string header
</p></dd><dt><span class=
"term">UNISTR
</span></dt><dd><p>domain SID unicode string
</p></dd></dl></div><p><span class=
"emphasis"><em>Note: there is a conflict between the unicode string header and the unicode string itself as to which to use to indicate string length. this will need to be resolved.
</em></span></p><p><span class=
"emphasis"><em>Note: the SID type indicates, for example, an alias; a well-known group etc. this is documented somewhere.
</em></span></p></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2874288"></a>DOM_RID (domain RID structure)
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT32
</span></dt><dd><p>5 - well-known SID.
1 - user SID (see ShowACLs)
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>5 - undocumented
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>domain RID
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>0 - domain index out of above reference domains
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2874358"></a>LOG_INFO (server, account, client structure)
</h4></div></div><div></div></div><p><span class=
"emphasis"><em>Note: logon server name starts with two '\' characters and is upper case.
</em></span></p><p><span class=
"emphasis"><em>Note: account name is the logon client name from the LSA Request Challenge, with a $ on the end of it, in upper case.
</em></span></p><div class=
"variablelist"><dl><dt><span class=
"term">VOID*
</span></dt><dd><p>undocumented buffer pointer
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>logon server unicode string
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>account name unicode string
</p></dd><dt><span class=
"term">UINT16
</span></dt><dd><p>sec_chan - security channel type
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>logon client machine unicode string
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2874457"></a>CLNT_SRV (server, client names structure)
</h4></div></div><div></div></div><p><span class=
"emphasis"><em>Note: logon server name starts with two '\' characters and is upper case.
</em></span></p><div class=
"variablelist"><dl><dt><span class=
"term">VOID*
</span></dt><dd><p>undocumented buffer pointer
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>logon server unicode string
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>undocumented buffer pointer
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>logon client machine unicode string
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2874535"></a>CREDS (credentials + time stamp)
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">char[
8]
</span></dt><dd><p>credentials
</p></dd><dt><span class=
"term">UTIME
</span></dt><dd><p>time stamp
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2874576"></a>CLNT_INFO2 (server, client structure, client credentials)
</h4></div></div><div></div></div><p><span class=
"emphasis"><em>Note: whenever this structure appears in a request, you must take a copy of the client-calculated credentials received, because they will beused in subsequent credential checks. the presumed intention is to
1227 maintain an authenticated request/response trail.
</em></span></p><div class=
"variablelist"><dl><dt><span class=
"term">CLNT_SRV
</span></dt><dd><p>client and server names
</p></dd><dt><span class=
"term">UINT8[]
</span></dt><dd><p>???? padding, for
4-byte alignment with SMB header.
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>pointer to client credentials.
</p></dd><dt><span class=
"term">CREDS
</span></dt><dd><p>client-calculated credentials + client time
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2874658"></a>CLNT_INFO (server, account, client structure, client credentials)
</h4></div></div><div></div></div><p><span class=
"emphasis"><em>Note: whenever this structure appears in a request, you must take a copy of the client-calculated credentials received, because they will be used in subsequent credential checks. the presumed intention is to maintain an authenticated request/response trail.
</em></span></p><div class=
"variablelist"><dl><dt><span class=
"term">LOG_INFO
</span></dt><dd><p>logon account info
</p></dd><dt><span class=
"term">CREDS
</span></dt><dd><p>client-calculated credentials + client time
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2874711"></a>ID_INFO_1 (id info structure, auth level
1)
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">VOID*
</span></dt><dd><p>ptr_id_info_1
</p></dd><dt><span class=
"term">UNIHDR
</span></dt><dd><p>domain name unicode header
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>param control
</p></dd><dt><span class=
"term">UINT64
</span></dt><dd><p>logon ID
</p></dd><dt><span class=
"term">UNIHDR
</span></dt><dd><p>user name unicode header
</p></dd><dt><span class=
"term">UNIHDR
</span></dt><dd><p>workgroup name unicode header
</p></dd><dt><span class=
"term">char[
16]
</span></dt><dd><p>arc4 LM OWF Password
</p></dd><dt><span class=
"term">char[
16]
</span></dt><dd><p>arc4 NT OWF Password
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>domain name unicode string
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>user name unicode string
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>workstation name unicode string
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2874881"></a>SAM_INFO (sam logon/logoff id info structure)
</h4></div></div><div></div></div><p><span class=
"emphasis"><em>Note: presumably, the return credentials is supposedly for the server to verify that the credential chain hasn't been compromised.
</em></span></p><div class=
"variablelist"><dl><dt><span class=
"term">CLNT_INFO2
</span></dt><dd><p>client identification/authentication info
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>pointer to return credentials.
</p></dd><dt><span class=
"term">CRED
</span></dt><dd><p>return credentials - ignored.
</p></dd><dt><span class=
"term">UINT16
</span></dt><dd><p>logon level
</p></dd><dt><span class=
"term">UINT16
</span></dt><dd><p>switch value
</p></dd></dl></div><pre class=
"programlisting">
1228 switch (switch_value)
1231 ID_INFO_1 id_info_1;
1233 </pre></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2874984"></a>GID (group id info)
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT32
</span></dt><dd><p>group id
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>user attributes (only used by NT
3.1 and
3.51)
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2875023"></a>DOM_REF (domain reference info)
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">VOID*
</span></dt><dd><p>undocumented buffer pointer.
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>num referenced domains?
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>undocumented domain name buffer pointer.
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>32 - max number of entries
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>4 - num referenced domains?
</p></dd><dt><span class=
"term">UNIHDR2
</span></dt><dd><p>domain name unicode string header
</p></dd><dt><span class=
"term">UNIHDR2[num_ref_doms-
1]
</span></dt><dd><p>referenced domain unicode string headers
</p></dd><dt><span class=
"term">UNISTR
</span></dt><dd><p>domain name unicode string
</p></dd><dt><span class=
"term">DOM_SID[num_ref_doms]
</span></dt><dd><p>referenced domain SIDs
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2875166"></a>DOM_INFO (domain info, levels
3 and
5 are the same))
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT8[]
</span></dt><dd><p>??? padding to get
4-byte alignment with start of SMB header
</p></dd><dt><span class=
"term">UINT16
</span></dt><dd><p>domain name string length *
2</p></dd><dt><span class=
"term">UINT16
</span></dt><dd><p>domain name string length *
2</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>undocumented domain name string buffer pointer
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>undocumented domain SID string buffer pointer
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>domain name (unicode string)
</p></dd><dt><span class=
"term">DOM_SID
</span></dt><dd><p>domain SID
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2875279"></a>USER_INFO (user logon info)
</h4></div></div><div></div></div><p><span class=
"emphasis"><em>Note: it would be nice to know what the
16 byte user session key is for.
</em></span></p><div class=
"variablelist"><dl><dt><span class=
"term">NTTIME
</span></dt><dd><p>logon time
</p></dd><dt><span class=
"term">NTTIME
</span></dt><dd><p>logoff time
</p></dd><dt><span class=
"term">NTTIME
</span></dt><dd><p>kickoff time
</p></dd><dt><span class=
"term">NTTIME
</span></dt><dd><p>password last set time
</p></dd><dt><span class=
"term">NTTIME
</span></dt><dd><p>password can change time
</p></dd><dt><span class=
"term">NTTIME
</span></dt><dd><p>password must change time
</p></dd><dt><span class=
"term">UNIHDR
</span></dt><dd><p>username unicode string header
</p></dd><dt><span class=
"term">UNIHDR
</span></dt><dd><p>user's full name unicode string header
</p></dd><dt><span class=
"term">UNIHDR
</span></dt><dd><p>logon script unicode string header
</p></dd><dt><span class=
"term">UNIHDR
</span></dt><dd><p>profile path unicode string header
</p></dd><dt><span class=
"term">UNIHDR
</span></dt><dd><p>home directory unicode string header
</p></dd><dt><span class=
"term">UNIHDR
</span></dt><dd><p>home directory drive unicode string header
</p></dd><dt><span class=
"term">UINT16
</span></dt><dd><p>logon count
</p></dd><dt><span class=
"term">UINT16
</span></dt><dd><p>bad password count
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>User ID
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>Group ID
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>num groups
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>undocumented buffer pointer to groups.
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>user flags
</p></dd><dt><span class=
"term">char[
16]
</span></dt><dd><p>user session key
</p></dd><dt><span class=
"term">UNIHDR
</span></dt><dd><p>logon server unicode string header
</p></dd><dt><span class=
"term">UNIHDR
</span></dt><dd><p>logon domain unicode string header
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>undocumented logon domain id pointer
</p></dd><dt><span class=
"term">char[
40]
</span></dt><dd><p>40 undocumented padding bytes. future expansion?
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>0 - num_other_sids?
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>NULL - undocumented pointer to other domain SIDs.
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>username unicode string
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>user's full name unicode string
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>logon script unicode string
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>profile path unicode string
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>home directory unicode string
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>home directory drive unicode string
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>num groups
</p></dd><dt><span class=
"term">GID[num_groups]
</span></dt><dd><p>group info
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>logon server unicode string
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>logon domain unicode string
</p></dd><dt><span class=
"term">DOM_SID
</span></dt><dd><p>domain SID
</p></dd><dt><span class=
"term">DOM_SID[num_sids]
</span></dt><dd><p>other domain SIDs?
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2875843"></a>SH_INFO_1_PTR (pointers to level
1 share info strings)
</h4></div></div><div></div></div><p><span class=
"emphasis"><em>Note: see cifsrap2.txt section5, page
10.
</em></span></p><table class=
"simplelist" border=
"0" summary=
"Simple list"><tr><td>0 for shi1_type indicates a Disk.
</td></tr><tr><td>1 for shi1_type indicates a Print Queue.
</td></tr><tr><td>2 for shi1_type indicates a Device.
</td></tr><tr><td>3 for shi1_type indicates an IPC pipe.
</td></tr><tr><td>0x8000 0000 (top bit set in shi1_type) indicates a hidden share.
</td></tr></table><div class=
"variablelist"><dl><dt><span class=
"term">VOID*
</span></dt><dd><p>shi1_netname - pointer to net name
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>shi1_type - type of share.
0 - undocumented.
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>shi1_remark - pointer to comment.
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2875937"></a>SH_INFO_1_STR (level
1 share info strings)
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UNISTR2
</span></dt><dd><p>shi1_netname - unicode string of net name
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>shi1_remark - unicode string of comment.
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2875980"></a>SHARE_INFO_1_CTR
</h4></div></div><div></div></div><p>share container with
0 entries:
</p><div class=
"variablelist"><dl><dt><span class=
"term">UINT32
</span></dt><dd><p>0 - EntriesRead
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>0 - Buffer
</p></dd></dl></div><p>share container with
> 0 entries:
</p><div class=
"variablelist"><dl><dt><span class=
"term">UINT32
</span></dt><dd><p>EntriesRead
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>non-zero - Buffer
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>EntriesRead
</p></dd><dt><span class=
"term">SH_INFO_1_PTR[EntriesRead]
</span></dt><dd><p>share entry pointers
</p></dd><dt><span class=
"term">SH_INFO_1_STR[EntriesRead]
</span></dt><dd><p>share entry strings
</p></dd><dt><span class=
"term">UINT8[]
</span></dt><dd><p>padding to get unicode string
4-byte aligned with start of the SMB header.
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>EntriesRead
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>0 - padding
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2876149"></a>SERVER_INFO_101
</h4></div></div><div></div></div><p><span class=
"emphasis"><em>Note: see cifs6.txt section
6.4 - the fields described therein will be of assistance here. for example, the type listed below is the same as fServerType, which is described in
6.4.1.
</em></span></p><div class=
"variablelist"><dl><dt><span class=
"term">SV_TYPE_WORKSTATION
</span></dt><dd><p>0x00000001 All workstations
</p></dd><dt><span class=
"term">SV_TYPE_SERVER
</span></dt><dd><p>0x00000002 All servers
</p></dd><dt><span class=
"term">SV_TYPE_SQLSERVER
</span></dt><dd><p>0x00000004 Any server running with SQL server
</p></dd><dt><span class=
"term">SV_TYPE_DOMAIN_CTRL
</span></dt><dd><p>0x00000008 Primary domain controller
</p></dd><dt><span class=
"term">SV_TYPE_DOMAIN_BAKCTRL
</span></dt><dd><p>0x00000010 Backup domain controller
</p></dd><dt><span class=
"term">SV_TYPE_TIME_SOURCE
</span></dt><dd><p>0x00000020 Server running the timesource service
</p></dd><dt><span class=
"term">SV_TYPE_AFP
</span></dt><dd><p>0x00000040 Apple File Protocol servers
</p></dd><dt><span class=
"term">SV_TYPE_NOVELL
</span></dt><dd><p>0x00000080 Novell servers
</p></dd><dt><span class=
"term">SV_TYPE_DOMAIN_MEMBER
</span></dt><dd><p>0x00000100 Domain Member
</p></dd><dt><span class=
"term">SV_TYPE_PRINTQ_SERVER
</span></dt><dd><p>0x00000200 Server sharing print queue
</p></dd><dt><span class=
"term">SV_TYPE_DIALIN_SERVER
</span></dt><dd><p>0x00000400 Server running dialin service.
</p></dd><dt><span class=
"term">SV_TYPE_XENIX_SERVER
</span></dt><dd><p>0x00000800 Xenix server
</p></dd><dt><span class=
"term">SV_TYPE_NT
</span></dt><dd><p>0x00001000 NT server
</p></dd><dt><span class=
"term">SV_TYPE_WFW
</span></dt><dd><p>0x00002000 Server running Windows for
</p></dd><dt><span class=
"term">SV_TYPE_SERVER_NT
</span></dt><dd><p>0x00008000 Windows NT non DC server
</p></dd><dt><span class=
"term">SV_TYPE_POTENTIAL_BROWSER
</span></dt><dd><p>0x00010000 Server that can run the browser service
</p></dd><dt><span class=
"term">SV_TYPE_BACKUP_BROWSER
</span></dt><dd><p>0x00020000 Backup browser server
</p></dd><dt><span class=
"term">SV_TYPE_MASTER_BROWSER
</span></dt><dd><p>0x00040000 Master browser server
</p></dd><dt><span class=
"term">SV_TYPE_DOMAIN_MASTER
</span></dt><dd><p>0x00080000 Domain Master Browser server
</p></dd><dt><span class=
"term">SV_TYPE_LOCAL_LIST_ONLY
</span></dt><dd><p>0x40000000 Enumerate only entries marked
"local
"</p></dd><dt><span class=
"term">SV_TYPE_DOMAIN_ENUM
</span></dt><dd><p>0x80000000 Enumerate Domains. The pszServer and pszDomain parameters must be NULL.
</p></dd></dl></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT32
</span></dt><dd><p>500 - platform_id
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>pointer to name
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>5 - major version
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>4 - minor version
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>type (SV_TYPE_... bit field)
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>pointer to comment
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>sv101_name - unicode string of server name
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>sv_101_comment - unicode string of server comment.
</p></dd><dt><span class=
"term">UINT8[]
</span></dt><dd><p>padding to get unicode string
4-byte aligned with start of the SMB header.
</p></dd></dl></div></div></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2876614"></a>MSRPC over Transact Named Pipe
</h2></div></div><div></div></div><p>For details on the SMB Transact Named Pipe, see cifs6.txt
</p><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2876627"></a>MSRPC Pipes
</h3></div></div><div></div></div><p>
1234 The MSRPC is conducted over an SMB Transact Pipe with a name of
1235 <tt class=
"filename">\PIPE\
</tt>. You must first obtain a
16 bit file handle, by
1236 sending a SMBopenX with the pipe name
<tt class=
"filename">\PIPE\srvsvc
</tt> for
1237 example. You can then perform an SMB Trans,
1238 and must carry out an SMBclose on the file handle once you are finished.
1240 Trans Requests must be sent with two setup UINT16s, no UINT16 params (none
1241 known about), and UINT8 data parameters sufficient to contain the MSRPC
1242 header, and MSRPC data. The first UINT16 setup parameter must be either
1243 0x0026 to indicate an RPC, or
0x0001 to indicate Set Named Pipe Handle
1244 state. The second UINT16 parameter must be the file handle for the pipe,
1247 The Data section for an API Command of
0x0026 (RPC pipe) in the Trans
1248 Request is the RPC Header, followed by the RPC Data. The Data section for
1249 an API Command of
0x0001 (Set Named Pipe Handle state) is two bytes. The
1250 only value seen for these two bytes is
0x00 0x43.
1252 MSRPC Responses are sent as response data inside standard SMB Trans
1253 responses, with the MSRPC Header, MSRPC Data and MSRPC tail.
1255 It is suspected that the Trans Requests will need to be at least
2-byte
1256 aligned (probably
4-byte). This is standard practice for SMBs. It is also
1257 independent of the observed
4-byte alignments with the start of the MSRPC
1258 header, including the
4-byte alignment between the MSRPC header and the
1261 First, an SMBtconX connection is made to the IPC$ share. The connection
1262 must be made using encrypted passwords, not clear-text. Then, an SMBopenX
1263 is made on the pipe. Then, a Set Named Pipe Handle State must be sent,
1264 after which the pipe is ready to accept API commands. Lastly, and SMBclose
1269 lkcl/
01nov97 there appear to be two additional bytes after the null-terminated \PIPE\ name for the RPC pipe. Values seen so far are
1270 listed below:
</p><pre class=
"programlisting">
1271 initial SMBopenX request: RPC API command
0x26 params:
1272 "\\PIPE\\lsarpc
" 0x65 0x63;
0x72 0x70;
0x44 0x65;
1273 "\\PIPE\\srvsvc
" 0x73 0x76;
0x4E 0x00;
0x5C 0x43;
1274 </pre></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2876729"></a>Header
</h3></div></div><div></div></div><p>[section to be rewritten, following receipt of work by Duncan Stansfield]
</p><p>Interesting note: if you set packed data representation to
0x0100 0000
1275 then all
4-byte and
2-byte word ordering is turned around!
</p><p>The start of each of the NTLSA and NETLOGON named pipes begins with:
</p><div class=
"segmentedlist"><p><b>offset:
</b>00</p><p><b>Variable type:
</b>UINT8
</p><p><b>Variable data:
</b>5 - RPC major version
</p><p><b>offset:
</b>01</p><p><b>Variable type:
</b>UINT8
</p><p><b>Variable data:
</b>0 - RPC minor version
</p><p><b>offset:
</b>02</p><p><b>Variable type:
</b>UINT8
</p><p><b>Variable data:
</b>2 - RPC response packet
</p><p><b>offset:
</b>03</p><p><b>Variable type:
</b>UINT8
</p><p><b>Variable data:
</b>3 - (FirstFrag bit-wise or with LastFrag)
</p><p><b>offset:
</b>04</p><p><b>Variable type:
</b>UINT32
</p><p><b>Variable data:
</b>0x1000 0000 - packed data representation
</p><p><b>offset:
</b>08</p><p><b>Variable type:
</b>UINT16
</p><p><b>Variable data:
</b>fragment length - data size (bytes) inc header and tail.
</p><p><b>offset:
</b>0A
</p><p><b>Variable type:
</b>UINT16
</p><p><b>Variable data:
</b>0 - authentication length
</p><p><b>offset:
</b>0C
</p><p><b>Variable type:
</b>UINT32
</p><p><b>Variable data:
</b>call identifier. matches
12th UINT32 of incoming RPC data.
</p><p><b>offset:
</b>10</p><p><b>Variable type:
</b>UINT32
</p><p><b>Variable data:
</b>allocation hint - data size (bytes) minus header and tail.
</p><p><b>offset:
</b>14</p><p><b>Variable type:
</b>UINT16
</p><p><b>Variable data:
</b>0 - presentation context identifier
</p><p><b>offset:
</b>16</p><p><b>Variable type:
</b>UINT8
</p><p><b>Variable data:
</b>0 - cancel count
</p><p><b>offset:
</b>17</p><p><b>Variable type:
</b>UINT8
</p><p><b>Variable data:
</b>in replies:
0 - reserved; in requests: opnum - see #defines.
</p><p><b>offset:
</b>18</p><p><b>Variable type:
</b>......
</p><p><b>Variable data:
</b>start of data (goes on for allocation_hint bytes)
</p></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2876919"></a>RPC_Packet for request, response, bind and bind acknowledgement
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT8 versionmaj
</span></dt><dd><p>reply same as request (
0x05)
</p></dd><dt><span class=
"term">UINT8 versionmin
</span></dt><dd><p>reply same as request (
0x00)
</p></dd><dt><span class=
"term">UINT8 type
</span></dt><dd><p>one of the MSRPC_Type enums
</p></dd><dt><span class=
"term">UINT8 flags
</span></dt><dd><p>reply same as request (
0x00 for Bind,
0x03 for Request)
</p></dd><dt><span class=
"term">UINT32 representation
</span></dt><dd><p>reply same as request (
0x00000010)
</p></dd><dt><span class=
"term">UINT16 fraglength
</span></dt><dd><p>the length of the data section of the SMB trans packet
</p></dd><dt><span class=
"term">UINT16 authlength
</span></dt><dd><p></p></dd><dt><span class=
"term">UINT32 callid
</span></dt><dd><p>call identifier. (e.g.
0x00149594)
</p></dd><dt><span class=
"term">* stub USE TvPacket
</span></dt><dd><p>the remainder of the packet depending on the
"type
"</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2877052"></a>Interface identification
</h4></div></div><div></div></div><p>the interfaces are numbered. as yet I haven't seen more than one interface used on the same pipe name srvsvc
</p><pre class=
"programlisting">
1276 abstract (
0x4B324FC8,
0x01D31670,
0x475A7812,
0x88E16EBF,
0x00000003)
1277 transfer (
0x8A885D04,
0x11C91CEB,
0x0008E89F,
0x6048102B,
0x00000002)
1278 </pre></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2877078"></a>RPC_Iface RW
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT8 byte[
16]
</span></dt><dd><p>16 bytes of number
</p></dd><dt><span class=
"term">UINT32 version
</span></dt><dd><p>the interface number
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2877117"></a>RPC_ReqBind RW
</h4></div></div><div></div></div><p>the remainder of the packet after the header if
"type
" was Bind in the response header,
"type
" should be BindAck
</p><div class=
"variablelist"><dl><dt><span class=
"term">UINT16 maxtsize
</span></dt><dd><p>maximum transmission fragment size (
0x1630)
</p></dd><dt><span class=
"term">UINT16 maxrsize
</span></dt><dd><p>max receive fragment size (
0x1630)
</p></dd><dt><span class=
"term">UINT32 assocgid
</span></dt><dd><p>associated group id (
0x0)
</p></dd><dt><span class=
"term">UINT32 numelements
</span></dt><dd><p>the number of elements (
0x1)
</p></dd><dt><span class=
"term">UINT16 contextid
</span></dt><dd><p>presentation context identifier (
0x0)
</p></dd><dt><span class=
"term">UINT8 numsyntaxes
</span></dt><dd><p>the number of syntaxes (has always been
1?)(
0x1)
</p></dd><dt><span class=
"term">UINT8[]
</span></dt><dd><p>4-byte alignment padding, against SMB header
</p></dd><dt><span class=
"term">* abstractint USE RPC_Iface
</span></dt><dd><p>num and vers. of interface client is using
</p></dd><dt><span class=
"term">* transferint USE RPC_Iface
</span></dt><dd><p>num and vers. of interface to use for replies
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2877258"></a>RPC_Address RW
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT16 length
</span></dt><dd><p>length of the string including null terminator
</p></dd><dt><span class=
"term">* port USE string
</span></dt><dd><p>the string above in single byte, null terminated form
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2877298"></a>RPC_ResBind RW
</h4></div></div><div></div></div><p>the response to place after the header in the reply packet
</p><div class=
"variablelist"><dl><dt><span class=
"term">UINT16 maxtsize
</span></dt><dd><p>same as request
</p></dd><dt><span class=
"term">UINT16 maxrsize
</span></dt><dd><p>same as request
</p></dd><dt><span class=
"term">UINT32 assocgid
</span></dt><dd><p>zero
</p></dd><dt><span class=
"term">* secondaddr USE RPC_Address
</span></dt><dd><p>the address string, as described earlier
</p></dd><dt><span class=
"term">UINT8[]
</span></dt><dd><p>4-byte alignment padding, against SMB header
</p></dd><dt><span class=
"term">UINT8 numresults
</span></dt><dd><p>the number of results (
0x01)
</p></dd><dt><span class=
"term">UINT8[]
</span></dt><dd><p>4-byte alignment padding, against SMB header
</p></dd><dt><span class=
"term">UINT16 result
</span></dt><dd><p>result (
0x00 = accept)
</p></dd><dt><span class=
"term">UINT16 reason
</span></dt><dd><p>reason (
0x00 = no reason specified)
</p></dd><dt><span class=
"term">* transfersyntax USE RPC_Iface
</span></dt><dd><p>the transfer syntax from the request
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2877448"></a>RPC_ReqNorm RW
</h4></div></div><div></div></div><p>the remainder of the packet after the header for every other other request
</p><div class=
"variablelist"><dl><dt><span class=
"term">UINT32 allochint
</span></dt><dd><p>the size of the stub data in bytes
</p></dd><dt><span class=
"term">UINT16 prescontext
</span></dt><dd><p>presentation context identifier (
0x0)
</p></dd><dt><span class=
"term">UINT16 opnum
</span></dt><dd><p>operation number (
0x15)
</p></dd><dt><span class=
"term">* stub USE TvPacket
</span></dt><dd><p>a packet dependent on the pipe name (probably the interface) and the op number)
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2877519"></a>RPC_ResNorm RW
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT32 allochint
</span></dt><dd><p># size of the stub data in bytes
</p></dd><dt><span class=
"term">UINT16 prescontext
</span></dt><dd><p># presentation context identifier (same as request)
</p></dd><dt><span class=
"term">UINT8 cancelcount
</span></dt><dd><p># cancel count? (
0x0)
</p></dd><dt><span class=
"term">UINT8 reserved
</span></dt><dd><p>#
0 - one byte padding
</p></dd><dt><span class=
"term">* stub USE TvPacket
</span></dt><dd><p># the remainder of the reply
</p></dd></dl></div></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2877600"></a>Tail
</h3></div></div><div></div></div><p>The end of each of the NTLSA and NETLOGON named pipes ends with:
</p><div class=
"variablelist"><dl><dt><span class=
"term">......
</span></dt><dd><p>end of data
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>return code
</p></dd></dl></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2877647"></a>RPC Bind / Bind Ack
</h3></div></div><div></div></div><p>
1279 RPC Binds are the process of associating an RPC pipe (e.g \PIPE\lsarpc)
1280 with a
"transfer syntax
" (see RPC_Iface structure). The purpose for doing
1282 </p><p><span class=
"emphasis"><em>Note: The RPC_ResBind SMB Transact request is sent with two uint16 setup parameters. The first is
0x0026; the second is the file handle
1283 returned by the SMBopenX Transact response.
</em></span></p><p><span class=
"emphasis"><em>Note: The RPC_ResBind members maxtsize, maxrsize and assocgid are the same in the response as the same members in the RPC_ReqBind. The
1284 RPC_ResBind member transfersyntax is the same in the response as
1285 the
</em></span></p><p><span class=
"emphasis"><em>Note: The RPC_ResBind response member secondaddr contains the name of what is presumed to be the service behind the RPC pipe. The
1286 mapping identified so far is:
</em></span></p><div class=
"variablelist"><dl><dt><span class=
"term">initial SMBopenX request:
</span></dt><dd><p>RPC_ResBind response:
</p></dd><dt><span class=
"term">"\\PIPE\\srvsvc
"</span></dt><dd><p>"\\PIPE\\ntsvcs
"</p></dd><dt><span class=
"term">"\\PIPE\\samr
"</span></dt><dd><p>"\\PIPE\\lsass
"</p></dd><dt><span class=
"term">"\\PIPE\\lsarpc
"</span></dt><dd><p>"\\PIPE\\lsass
"</p></dd><dt><span class=
"term">"\\PIPE\\wkssvc
"</span></dt><dd><p>"\\PIPE\\wksvcs
"</p></dd><dt><span class=
"term">"\\PIPE\\NETLOGON
"</span></dt><dd><p>"\\PIPE\\NETLOGON
"</p></dd></dl></div><p><span class=
"emphasis"><em>Note: The RPC_Packet fraglength member in both the Bind Request and Bind Acknowledgment must contain the length of the entire RPC data, including the RPC_Packet header.
</em></span></p><p>Request:
</p><table class=
"simplelist" border=
"0" summary=
"Simple list"><tr><td>RPC_Packet
</td></tr><tr><td>RPC_ReqBind
</td></tr></table><p>Response:
</p><table class=
"simplelist" border=
"0" summary=
"Simple list"><tr><td>RPC_Packet
</td></tr><tr><td>RPC_ResBind
</td></tr></table></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2877826"></a>NTLSA Transact Named Pipe
</h3></div></div><div></div></div><p>The sequence of actions taken on this pipe are:
</p><table class=
"simplelist" border=
"0" summary=
"Simple list"><tr><td>Establish a connection to the IPC$ share (SMBtconX). use encrypted passwords.
</td></tr><tr><td>Open an RPC Pipe with the name
"\\PIPE\\lsarpc
". Store the file handle.
</td></tr><tr><td>Using the file handle, send a Set Named Pipe Handle state to
0x4300.
</td></tr><tr><td>Send an LSA Open Policy request. Store the Policy Handle.
</td></tr><tr><td>Using the Policy Handle, send LSA Query Info Policy requests, etc.
</td></tr><tr><td>Using the Policy Handle, send an LSA Close.
</td></tr><tr><td>Close the IPC$ share.
</td></tr></table><p>Defines for this pipe, identifying the query are:
</p><div class=
"variablelist"><dl><dt><span class=
"term">LSA Open Policy:
</span></dt><dd><p>0x2c</p></dd><dt><span class=
"term">LSA Query Info Policy:
</span></dt><dd><p>0x07</p></dd><dt><span class=
"term">LSA Enumerate Trusted Domains:
</span></dt><dd><p>0x0d</p></dd><dt><span class=
"term">LSA Open Secret:
</span></dt><dd><p>0xff</p></dd><dt><span class=
"term">LSA Lookup SIDs:
</span></dt><dd><p>0xfe</p></dd><dt><span class=
"term">LSA Lookup Names:
</span></dt><dd><p>0xfd</p></dd><dt><span class=
"term">LSA Close:
</span></dt><dd><p>0x00</p></dd></dl></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2877991"></a>LSA Open Policy
</h3></div></div><div></div></div><p><span class=
"emphasis"><em>Note: The policy handle can be anything you like.
</em></span></p><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2878004"></a>Request
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">VOID*
</span></dt><dd><p>buffer pointer
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>server name - unicode string starting with two '\'s
</p></dd><dt><span class=
"term">OBJ_ATTR
</span></dt><dd><p>object attributes
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>1 - desired access
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2878075"></a>Response
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">POL_HND
</span></dt><dd><p>LSA policy handle
</p></dd><dt><span class=
"term">return
</span></dt><dd><p>0 - indicates success
</p></dd></dl></div></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2878118"></a>LSA Query Info Policy
</h3></div></div><div></div></div><p><span class=
"emphasis"><em>Note: The info class in response must be the same as that in the request.
</em></span></p><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2878132"></a>Request
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">POL_HND
</span></dt><dd><p>LSA policy handle
</p></dd><dt><span class=
"term">UINT16
</span></dt><dd><p>info class (also a policy handle?)
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2878170"></a>Response
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">VOID*
</span></dt><dd><p>undocumented buffer pointer
</p></dd><dt><span class=
"term">UINT16
</span></dt><dd><p>info class (same as info class in request).
</p></dd></dl></div><pre class=
"programlisting">
1291 DOM_INFO domain info, levels
3 and
5 (are the same).
1294 return
0 - indicates success
1295 </pre></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2878223"></a>LSA Enumerate Trusted Domains
</h3></div></div><div></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2878230"></a>Request
</h4></div></div><div></div></div><p>no extra data
</p></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2878243"></a>Response
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT32
</span></dt><dd><p>0 - enumeration context
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>0 - entries read
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>0 - trust information
</p></dd><dt><span class=
"term">return
</span></dt><dd><p>0x8000 001a -
"no trusted domains
" success code
</p></dd></dl></div></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2878315"></a>LSA Open Secret
</h3></div></div><div></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2878322"></a>Request
</h4></div></div><div></div></div><p>no extra data
</p></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2878334"></a>Response
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT32
</span></dt><dd><p>0 - undocumented
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>0 - undocumented
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>0 - undocumented
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>0 - undocumented
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>0 - undocumented
</p></dd></dl></div><p>return
0x0C00 0034 -
"no such secret
" success code
</p></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2878424"></a>LSA Close
</h3></div></div><div></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2878432"></a>Request
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">POL_HND
</span></dt><dd><p>policy handle to be closed
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2878459"></a>Response
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">POL_HND
</span></dt><dd><p>0s - closed policy handle (all zeros)
</p></dd></dl></div><p>return
0 - indicates success
</p></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2878490"></a>LSA Lookup SIDS
</h3></div></div><div></div></div><p><span class=
"emphasis"><em>Note: num_entries in response must be same as num_entries in request.
</em></span></p><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2878504"></a>Request
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">POL_HND
</span></dt><dd><p>LSA policy handle
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>num_entries
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>undocumented domain SID buffer pointer
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>undocumented domain name buffer pointer
</p></dd><dt><span class=
"term">VOID*[num_entries] undocumented domain SID pointers to be looked up.
1296 </span></dt><dd><p>DOM_SID[num_entries] domain SIDs to be looked up.
</p></dd><dt><span class=
"term">char[
16]
</span></dt><dd><p>completely undocumented
16 bytes.
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2878604"></a>Response
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">DOM_REF
</span></dt><dd><p>domain reference response
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>num_entries (listed above)
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>undocumented buffer pointer
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>num_entries (listed above)
</p></dd><dt><span class=
"term">DOM_SID2[num_entries]
</span></dt><dd><p>domain SIDs (from Request, listed above).
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>num_entries (listed above)
</p></dd></dl></div><p>return
0 - indicates success
</p></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2878700"></a>LSA Lookup Names
</h3></div></div><div></div></div><p><span class=
"emphasis"><em>Note: num_entries in response must be same as num_entries in request.
</em></span></p><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2878714"></a>Request
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">POL_HND
</span></dt><dd><p>LSA policy handle
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>num_entries
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>num_entries
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>undocumented domain SID buffer pointer
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>undocumented domain name buffer pointer
</p></dd><dt><span class=
"term">NAME[num_entries]
</span></dt><dd><p>names to be looked up.
</p></dd><dt><span class=
"term">char[]
</span></dt><dd><p>undocumented bytes - falsely translated SID structure?
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2878828"></a>Response
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">DOM_REF
</span></dt><dd><p>domain reference response
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>num_entries (listed above)
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>undocumented buffer pointer
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>num_entries (listed above)
</p></dd><dt><span class=
"term">DOM_RID[num_entries]
</span></dt><dd><p>domain SIDs (from Request, listed above).
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>num_entries (listed above)
</p></dd></dl></div><p>return
0 - indicates success
</p></div></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2878926"></a>NETLOGON rpc Transact Named Pipe
</h2></div></div><div></div></div><p>The sequence of actions taken on this pipe are:
</p><table class=
"simplelist" border=
"0" summary=
"Simple list"><tr><td>tablish a connection to the IPC$ share (SMBtconX). use encrypted passwords.
</td></tr><tr><td>en an RPC Pipe with the name
"\\PIPE\\NETLOGON
". Store the file handle.
</td></tr><tr><td>ing the file handle, send a Set Named Pipe Handle state to
0x4300.
</td></tr><tr><td>eate Client Challenge. Send LSA Request Challenge. Store Server Challenge.
</td></tr><tr><td>lculate Session Key. Send an LSA Auth
2 Challenge. Store Auth2 Challenge.
</td></tr><tr><td>lc/Verify Client Creds. Send LSA Srv PW Set. Calc/Verify Server Creds.
</td></tr><tr><td>lc/Verify Client Creds. Send LSA SAM Logon . Calc/Verify Server Creds.
</td></tr><tr><td>lc/Verify Client Creds. Send LSA SAM Logoff. Calc/Verify Server Creds.
</td></tr><tr><td>ose the IPC$ share.
</td></tr></table><p>Defines for this pipe, identifying the query are
</p><div class=
"variablelist"><dl><dt><span class=
"term">LSA Request Challenge:
</span></dt><dd><p>0x04</p></dd><dt><span class=
"term">LSA Server Password Set:
</span></dt><dd><p>0x06</p></dd><dt><span class=
"term">LSA SAM Logon:
</span></dt><dd><p>0x02</p></dd><dt><span class=
"term">LSA SAM Logoff:
</span></dt><dd><p>0x03</p></dd><dt><span class=
"term">LSA Auth
2:
</span></dt><dd><p>0x0f</p></dd><dt><span class=
"term">LSA Logon Control:
</span></dt><dd><p>0x0e</p></dd></dl></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2879087"></a>LSA Request Challenge
</h3></div></div><div></div></div><p><span class=
"emphasis"><em>Note: logon server name starts with two '\' characters and is upper case.
</em></span></p><p><span class=
"emphasis"><em>Note: logon client is the machine, not the user.
</em></span></p><p><span class=
"emphasis"><em>Note: the initial LanManager password hash, against which the challenge is issued, is the machine name itself (lower case). there will becalls issued (LSA Server Password Set) which will change this, later. refusing these calls allows you to always deal with the same password (i.e the LM# of the machine name in lower case).
</em></span></p><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2879119"></a>Request
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">VOID*
</span></dt><dd><p>undocumented buffer pointer
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>logon server unicode string
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>logon client unicode string
</p></dd><dt><span class=
"term">char[
8]
</span></dt><dd><p>client challenge
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2879189"></a>Response
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">char[
8]
</span></dt><dd><p>server challenge
</p></dd></dl></div><p>return
0 - indicates success
</p></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2879222"></a>LSA Authenticate
2</h3></div></div><div></div></div><p><span class=
"emphasis"><em>Note: in between request and response, calculate the client credentials, and check them against the client-calculated credentials (this process uses the previously received client credentials).
</em></span></p><p><span class=
"emphasis"><em>Note: neg_flags in the response is the same as that in the request.
</em></span></p><p><span class=
"emphasis"><em>Note: you must take a copy of the client-calculated credentials received here, because they will be used in subsequent authentication packets.
</em></span></p><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2879252"></a>Request
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">LOG_INFO
</span></dt><dd><p>client identification info
</p></dd><dt><span class=
"term">char[
8]
</span></dt><dd><p>client-calculated credentials
</p></dd><dt><span class=
"term">UINT8[]
</span></dt><dd><p>padding to
4-byte align with start of SMB header.
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>neg_flags - negotiated flags (usual value is
0x0000 01ff)
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2879321"></a>Response
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">char[
8]
</span></dt><dd><p>server credentials.
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>neg_flags - same as neg_flags in request.
</p></dd></dl></div><p>return
0 - indicates success. failure value unknown.
</p></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2879369"></a>LSA Server Password Set
</h3></div></div><div></div></div><p><span class=
"emphasis"><em>Note: the new password is suspected to be a DES encryption using the old password to generate the key.
</em></span></p><p><span class=
"emphasis"><em>Note: in between request and response, calculate the client credentials, and check them against the client-calculated credentials (this process uses the previously received client credentials).
</em></span></p><p><span class=
"emphasis"><em>Note: the server credentials are constructed from the client-calculated credentials and the client time +
1 second.
</em></span></p><p><span class=
"emphasis"><em>Note: you must take a copy of the client-calculated credentials received here, because they will be used in subsequent authentication packets.
</em></span></p><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2879408"></a>Request
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">CLNT_INFO
</span></dt><dd><p>client identification/authentication info
</p></dd><dt><span class=
"term">char[]
</span></dt><dd><p>new password - undocumented.
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2879450"></a>Response
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">CREDS
</span></dt><dd><p>server credentials. server time stamp appears to be ignored.
</p></dd></dl></div><p>return
0 - indicates success;
0xC000 006a indicates failure
</p></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2879484"></a>LSA SAM Logon
</h3></div></div><div></div></div><p><span class=
"emphasis"><em>
1297 Note: valid_user is True iff the username and password hash are valid for
1298 the requested domain.
1299 </em></span></p><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2879498"></a>Request
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">SAM_INFO
</span></dt><dd><p>sam_id structure
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2879526"></a>Response
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">VOID*
</span></dt><dd><p>undocumented buffer pointer
</p></dd><dt><span class=
"term">CREDS
</span></dt><dd><p>server credentials. server time stamp appears to be ignored.
</p></dd></dl></div><pre class=
"programlisting">
1302 UINT16
3 - switch value indicating USER_INFO structure.
1303 VOID* non-zero - pointer to USER_INFO structure
1304 USER_INFO user logon information
1306 UINT32
1 - Authoritative response;
0 - Non-Auth?
1308 return
0 - indicates success
1312 UINT16
0 - switch value. value to indicate no user presumed.
1313 VOID*
0x0000 0000 - indicates no USER_INFO structure.
1315 UINT32
1 - Authoritative response;
0 - Non-Auth?
1317 return
0xC000 0064 - NT_STATUS_NO_SUCH_USER.
1319 </pre></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2879598"></a>LSA SAM Logoff
</h3></div></div><div></div></div><p><span class=
"emphasis"><em>
1320 Note: presumably, the SAM_INFO structure is validated, and a (currently
1321 undocumented) error code returned if the Logoff is invalid.
1322 </em></span></p><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2879612"></a>Request
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">SAM_INFO
</span></dt><dd><p>sam_id structure
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2879639"></a>Response
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">VOID*
</span></dt><dd><p>undocumented buffer pointer
</p></dd><dt><span class=
"term">CREDS
</span></dt><dd><p>server credentials. server time stamp appears to be ignored.
</p></dd></dl></div><p>return
0 - indicates success. undocumented failure indication.
</p></div></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2879689"></a>\\MAILSLOT\NET\NTLOGON
</h2></div></div><div></div></div><p><span class=
"emphasis"><em>
1323 Note: mailslots will contain a response mailslot, to which the response
1324 should be sent. the target NetBIOS name is REQUEST_NAME
<20>, where
1325 REQUEST_NAME is the name of the machine that sent the request.
1326 </em></span></p><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2879701"></a>Query for PDC
</h3></div></div><div></div></div><p><span class=
"emphasis"><em>Note: NTversion, LMNTtoken, LM20token in response are the same as those given in the request.
</em></span></p><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2879721"></a>Request
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT16
</span></dt><dd><p>0x0007 - Query for PDC
</p></dd><dt><span class=
"term">STR
</span></dt><dd><p>machine name
</p></dd><dt><span class=
"term">STR
</span></dt><dd><p>response mailslot
</p></dd><dt><span class=
"term">UINT8[]
</span></dt><dd><p>padding to
2-byte align with start of mailslot.
</p></dd><dt><span class=
"term">UNISTR
</span></dt><dd><p>machine name
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>NTversion
</p></dd><dt><span class=
"term">UINT16
</span></dt><dd><p>LMNTtoken
</p></dd><dt><span class=
"term">UINT16
</span></dt><dd><p>LM20token
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2879848"></a>Response
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT16
</span></dt><dd><p>0x000A - Respose to Query for PDC
</p></dd><dt><span class=
"term">STR
</span></dt><dd><p>machine name (in uppercase)
</p></dd><dt><span class=
"term">UINT8[]
</span></dt><dd><p>padding to
2-byte align with start of mailslot.
</p></dd><dt><span class=
"term">UNISTR
</span></dt><dd><p>machine name
</p></dd><dt><span class=
"term">UNISTR
</span></dt><dd><p>domain name
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>NTversion (same as received in request)
</p></dd><dt><span class=
"term">UINT16
</span></dt><dd><p>LMNTtoken (same as received in request)
</p></dd><dt><span class=
"term">UINT16
</span></dt><dd><p>LM20token (same as received in request)
</p></dd></dl></div></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2879969"></a>SAM Logon
</h3></div></div><div></div></div><p><span class=
"emphasis"><em>Note: machine name in response is preceded by two '\' characters.
</em></span></p><p><span class=
"emphasis"><em>Note: NTversion, LMNTtoken, LM20token in response are the same as those given in the request.
</em></span></p><p><span class=
"emphasis"><em>Note: user name in the response is presumably the same as that in the request.
</em></span></p><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2879997"></a>Request
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT16
</span></dt><dd><p>0x0012 - SAM Logon
</p></dd><dt><span class=
"term">UINT16
</span></dt><dd><p>request count
</p></dd><dt><span class=
"term">UNISTR
</span></dt><dd><p>machine name
</p></dd><dt><span class=
"term">UNISTR
</span></dt><dd><p>user name
</p></dd><dt><span class=
"term">STR
</span></dt><dd><p>response mailslot
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>alloweable account
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>domain SID size
</p></dd><dt><span class=
"term">char[sid_size]
</span></dt><dd><p>domain SID, of sid_size bytes.
</p></dd><dt><span class=
"term">UINT8[]
</span></dt><dd><p>???? padding to
4?
2? -byte align with start of mailslot.
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>NTversion
</p></dd><dt><span class=
"term">UINT16
</span></dt><dd><p>LMNTtoken
</p></dd><dt><span class=
"term">UINT16
</span></dt><dd><p>LM20token
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2880180"></a>Response
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT16
</span></dt><dd><p>0x0013 - Response to SAM Logon
</p></dd><dt><span class=
"term">UNISTR
</span></dt><dd><p>machine name
</p></dd><dt><span class=
"term">UNISTR
</span></dt><dd><p>user name - workstation trust account
</p></dd><dt><span class=
"term">UNISTR
</span></dt><dd><p>domain name
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>NTversion
</p></dd><dt><span class=
"term">UINT16
</span></dt><dd><p>LMNTtoken
</p></dd><dt><span class=
"term">UINT16
</span></dt><dd><p>LM20token
</p></dd></dl></div></div></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2880294"></a>SRVSVC Transact Named Pipe
</h2></div></div><div></div></div><p>Defines for this pipe, identifying the query are:
</p><div class=
"variablelist"><dl><dt><span class=
"term">Net Share Enum
</span></dt><dd><p>0x0f</p></dd><dt><span class=
"term">Net Server Get Info
</span></dt><dd><p>0x15</p></dd></dl></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2880339"></a>Net Share Enum
</h3></div></div><div></div></div><p><span class=
"emphasis"><em>Note: share level and switch value in the response are presumably the same as those in the request.
</em></span></p><p><span class=
"emphasis"><em>Note: cifsrap2.txt (section
5) may be of limited assistance here.
</em></span></p><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2880360"></a>Request
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">VOID*
</span></dt><dd><p>pointer (to server name?)
</p></dd><dt><span class=
"term">UNISTR2
</span></dt><dd><p>server name
</p></dd><dt><span class=
"term">UINT8[]
</span></dt><dd><p>padding to get unicode string
4-byte aligned with the start of the SMB header.
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>share level
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>switch value
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>pointer to SHARE_INFO_1_CTR
</p></dd><dt><span class=
"term">SHARE_INFO_1_CTR
</span></dt><dd><p>share info with
0 entries
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>preferred maximum length (
0xffff ffff)
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2880485"></a>Response
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT32
</span></dt><dd><p>share level
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>switch value
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>pointer to SHARE_INFO_1_CTR
</p></dd><dt><span class=
"term">SHARE_INFO_1_CTR
</span></dt><dd><p>share info (only added if share info ptr is non-zero)
</p></dd></dl></div><p>return
0 - indicates success
</p></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2880558"></a>Net Server Get Info
</h3></div></div><div></div></div><p><span class=
"emphasis"><em>Note: level is the same value as in the request.
</em></span></p><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2880572"></a>Request
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UNISTR2
</span></dt><dd><p>server name
</p></dd><dt><span class=
"term">UINT32
</span></dt><dd><p>switch level
</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2880613"></a>Response
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">UINT32
</span></dt><dd><p>switch level
</p></dd><dt><span class=
"term">VOID*
</span></dt><dd><p>pointer to SERVER_INFO_101
</p></dd><dt><span class=
"term">SERVER_INFO_101
</span></dt><dd><p>server info (only added if server info ptr is non-zero)
</p></dd></dl></div><p>return
0 - indicates success
</p></div></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2880674"></a>Cryptographic side of NT Domain Authentication
</h2></div></div><div></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2880682"></a>Definitions
</h3></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">Add(A1,A2)
</span></dt><dd><p>Intel byte ordered addition of corresponding
4 byte words in arrays A1 and A2
</p></dd><dt><span class=
"term">E(K,D)
</span></dt><dd><p>DES ECB encryption of
8 byte data D using
7 byte key K
</p></dd><dt><span class=
"term">lmowf()
</span></dt><dd><p>Lan man hash
</p></dd><dt><span class=
"term">ntowf()
</span></dt><dd><p>NT hash
</p></dd><dt><span class=
"term">PW
</span></dt><dd><p>md4(machine_password) == md4(lsadump $machine.acc) ==
1327 pwdump(machine$) (initially) == md4(lmowf(unicode(machine)))
1328 </p></dd><dt><span class=
"term">ARC4(K,Lk,D,Ld)
</span></dt><dd><p>ARC4 encryption of data D of length Ld with key K of length Lk
</p></dd><dt><span class=
"term">v[m..n(,l)]
</span></dt><dd><p>subset of v from bytes m to n, optionally padded with zeroes to length l
</p></dd><dt><span class=
"term">Cred(K,D)
</span></dt><dd><p>E(K[
7.
.7,
7],E(K[
0.
.6],D)) computes a credential
</p></dd><dt><span class=
"term">Time()
</span></dt><dd><p>4 byte current time
</p></dd><dt><span class=
"term">Cc,Cs
</span></dt><dd><p>8 byte client and server challenges Rc,Rs:
8 byte client and server credentials
</p></dd></dl></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2880845"></a>Protocol
</h3></div></div><div></div></div><pre class=
"programlisting">
1331 </pre><pre class=
"programlisting">
1332 C
& S compute session key Ks = E(PW[
9.
.15],E(PW[
0.
.6],Add(Cc,Cs)))
1333 </pre><pre class=
"programlisting">
1335 C-
>S Authenticate,Rc
1336 S: Rs = Cred(Ks,Cs), assert(Rc == Cred(Ks,Cc))
1338 C: assert(Rs == Cred(Ks,Cs))
1340 On joining the domain the client will optionally attempt to change its
1341 password and the domain controller may refuse to update it depending
1342 on registry settings. This will also occur weekly afterwards.
1343 </p><pre class=
"programlisting">
1344 C: Tc = Time(), Rc' = Cred(Ks,Rc+Tc)
1345 C-
>S ServerPasswordSet,Rc',Tc,arc4(Ks[
0.
.7,
16],lmowf(randompassword())
1346 C: Rc = Cred(Ks,Rc+Tc+
1)
1347 S: assert(Rc' == Cred(Ks,Rc+Tc)), Ts = Time()
1348 S: Rs' = Cred(Ks,Rs+Tc+
1)
1350 C: assert(Rs' == Cred(Ks,Rs+Tc+
1))
1353 User: U with password P wishes to login to the domain (incidental data
1354 such as workstation and domain omitted)
1355 </p><pre class=
"programlisting">
1356 C: Tc = Time(), Rc' = Cred(Ks,Rc+Tc)
1357 C-
>S NetLogonSamLogon,Rc',Tc,U,arc4(Ks[
0.
.7,
16],
16,ntowf(P),
16), arc4(Ks[
0.
.7,
16],
16,lmowf(P),
16)
1358 S: assert(Rc' == Cred(Ks,Rc+Tc)) assert(passwords match those in SAM)
1360 </pre><pre class=
"programlisting">
1361 S-
>C Cred(Ks,Cred(Ks,Rc+Tc+
1)),userinfo(logon script,UID,SIDs,etc)
1362 C: assert(Rs == Cred(Ks,Cred(Rc+Tc+
1))
1363 C: Rc = Cred(Ks,Rc+Tc+
1)
1364 </pre></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2880942"></a>Comments
</h3></div></div><div></div></div><p>
1365 On first joining the domain the session key could be computed by
1366 anyone listening in on the network as the machine password has a well
1367 known value. Until the machine is rebooted it will use this session
1368 key to encrypt NT and LM one way functions of passwords which are
1369 password equivalents. Any user who logs in before the machine has been
1370 rebooted a second time will have their password equivalent exposed. Of
1371 course the new machine password is exposed at this time anyway.
1373 None of the returned user info such as logon script, profile path and
1374 SIDs *appear* to be protected by anything other than the TCP checksum.
1376 The server time stamps appear to be ignored.
1378 The client sends a ReturnAuthenticator in the SamLogon request which I
1379 can't find a use for. However its time is used as the timestamp
1380 returned by the server.
1382 The password OWFs should NOT be sent over the network reversibly
1383 encrypted. They should be sent using ARC4(Ks,md4(owf)) with the server
1384 computing the same function using the owf values in the SAM.
1385 </p></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2880991"></a>SIDs and RIDs
</h2></div></div><div></div></div><p>
1386 SIDs and RIDs are well documented elsewhere.
1388 A SID is an NT Security ID (see DOM_SID structure). They are of the form:
1389 </p><table class=
"simplelist" border=
"0" summary=
"Simple list"><tr><td>revision-NN-SubAuth1-SubAuth2-SubAuth3...
</td></tr><tr><td>revision-
0xNNNNNNNNNNNN-SubAuth1-SubAuth2-SubAuth3...
</td></tr></table><p>
1390 currently, the SID revision is
1.
1391 The Sub-Authorities are known as Relative IDs (RIDs).
1392 </p><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2881031"></a>Well-known SIDs
</h3></div></div><div></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2881038"></a>Universal well-known SIDs
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">Null SID
</span></dt><dd><p>S-
1-
0-
0</p></dd><dt><span class=
"term">World
</span></dt><dd><p>S-
1-
1-
0</p></dd><dt><span class=
"term">Local
</span></dt><dd><p>S-
1-
2-
0</p></dd><dt><span class=
"term">Creator Owner ID
</span></dt><dd><p>S-
1-
3-
0</p></dd><dt><span class=
"term">Creator Group ID
</span></dt><dd><p>S-
1-
3-
1</p></dd><dt><span class=
"term">Creator Owner Server ID
</span></dt><dd><p>S-
1-
3-
2</p></dd><dt><span class=
"term">Creator Group Server ID
</span></dt><dd><p>S-
1-
3-
3</p></dd><dt><span class=
"term">(Non-unique IDs)
</span></dt><dd><p>S-
1-
4</p></dd></dl></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2881165"></a>NT well-known SIDs
</h4></div></div><div></div></div><div class=
"variablelist"><dl><dt><span class=
"term">NT Authority
</span></dt><dd><p>S-
1-
5</p></dd><dt><span class=
"term">Dialup
</span></dt><dd><p>S-
1-
5-
1</p></dd><dt><span class=
"term">Network
</span></dt><dd><p>S-
1-
5-
2</p></dd><dt><span class=
"term">Batch
</span></dt><dd><p>S-
1-
5-
3</p></dd><dt><span class=
"term">Interactive
</span></dt><dd><p>S-
1-
5-
4</p></dd><dt><span class=
"term">Service
</span></dt><dd><p>S-
1-
5-
6</p></dd><dt><span class=
"term">AnonymousLogon(aka null logon session)
</span></dt><dd><p>S-
1-
5-
7</p></dd><dt><span class=
"term">Proxy
</span></dt><dd><p>S-
1-
5-
8</p></dd><dt><span class=
"term">ServerLogon(aka domain controller account)
</span></dt><dd><p>S-
1-
5-
8</p></dd><dt><span class=
"term">(Logon IDs)
</span></dt><dd><p>S-
1-
5-
5-X-Y
</p></dd><dt><span class=
"term">(NT non-unique IDs)
</span></dt><dd><p>S-
1-
5-
0x15-...
</p></dd><dt><span class=
"term">(Built-in domain)
</span></dt><dd><p>s-
1-
5-
0x20</p></dd></dl></div></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2881346"></a>Well-known RIDS
</h3></div></div><div></div></div><p>
1393 A RID is a sub-authority value, as part of either a SID, or in the case
1394 of Group RIDs, part of the DOM_GID structure, in the USER_INFO_1
1395 structure, in the LSA SAM Logon response.
1396 </p><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2881360"></a>Well-known RID users
</h4></div></div><div></div></div><div class=
"segmentedlist"><p><b>Groupname:
</b>DOMAIN_USER_RID_ADMIN
</p><p><b>????:
</b>0x0000</p><p><b>RID:
</b>01F4
</p><p><b>Groupname:
</b>DOMAIN_USER_RID_GUEST
</p><p><b>????:
</b>0x0000</p><p><b>RID:
</b>01F5
</p></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2881409"></a>Well-known RID groups
</h4></div></div><div></div></div><div class=
"segmentedlist"><p><b>Groupname:
</b> DOMAIN_GROUP_RID_ADMINS
</p><p><b>????:
</b>0x0000</p><p><b>RID:
</b>0200</p><p><b>Groupname:
</b> DOMAIN_GROUP_RID_USERS
</p><p><b>????:
</b>0x0000</p><p><b>RID:
</b>0201</p><p><b>Groupname:
</b> DOMAIN_GROUP_RID_GUESTS
</p><p><b>????:
</b>0x0000</p><p><b>RID:
</b>0202</p></div></div><div class=
"sect3" lang=
"en"><div class=
"titlepage"><div><div><h4 class=
"title"><a name=
"id2881468"></a>Well-known RID aliases
</h4></div></div><div></div></div><div class=
"segmentedlist"><p><b>Groupname:
</b> DOMAIN_ALIAS_RID_ADMINS
</p><p><b>????:
</b>0x0000</p><p><b>RID:
</b>0220</p><p><b>Groupname:
</b> DOMAIN_ALIAS_RID_USERS
</p><p><b>????:
</b>0x0000</p><p><b>RID:
</b>0221</p><p><b>Groupname:
</b> DOMAIN_ALIAS_RID_GUESTS
</p><p><b>????:
</b>0x0000</p><p><b>RID:
</b>0222</p><p><b>Groupname:
</b> DOMAIN_ALIAS_RID_POWER_USERS
</p><p><b>????:
</b>0x0000</p><p><b>RID:
</b>0223</p><p><b>Groupname:
</b> DOMAIN_ALIAS_RID_ACCOUNT_OPS
</p><p><b>????:
</b>0x0000</p><p><b>RID:
</b>0224</p><p><b>Groupname:
</b> DOMAIN_ALIAS_RID_SYSTEM_OPS
</p><p><b>????:
</b>0x0000</p><p><b>RID:
</b>0225</p><p><b>Groupname:
</b> DOMAIN_ALIAS_RID_PRINT_OPS
</p><p><b>????:
</b>0x0000</p><p><b>RID:
</b>0226</p><p><b>Groupname:
</b> DOMAIN_ALIAS_RID_BACKUP_OPS
</p><p><b>????:
</b>0x0000</p><p><b>RID:
</b>0227</p><p><b>Groupname:
</b> DOMAIN_ALIAS_RID_REPLICATOR
</p><p><b>????:
</b>0x0000</p><p><b>RID:
</b>0228</p></div></div></div></div></div><div class=
"chapter" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title"><a name=
"printing"></a>Chapter
11. Samba Printing Internals
</h2></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Gerald
</span> <span class=
"surname">Carter
</span></h3></div></div><div><p class=
"pubdate">October
2002</p></div></div><div></div></div><div class=
"toc"><p><b>Table of Contents
</b></p><dl><dt><a href=
"#id2890028">Abstract
</a></dt><dt><a href=
"#id2890044">
1397 Printing Interface to Various Back ends
1398 </a></dt><dt><a href=
"#id2890298">
1400 </a></dt><dt><a href=
"#id2890507">
1401 ChangeID and Client Caching of Printer Information
1402 </a></dt><dt><a href=
"#id2890520">
1403 Windows NT/
2K Printer Change Notify
1404 </a></dt></dl></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2890028"></a>Abstract
</h2></div></div><div></div></div><p>
1405 The purpose of this document is to provide some insight into
1406 Samba's printing functionality and also to describe the semantics
1407 of certain features of Windows client printing.
1408 </p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2890044"></a>
1409 Printing Interface to Various Back ends
1410 </h2></div></div><div></div></div><p>
1411 Samba uses a table of function pointers to seven functions. The
1412 function prototypes are defined in the
<tt class=
"varname">printif
</tt> structure declared
1413 in
<tt class=
"filename">printing.h
</tt>.
1414 </p><div class=
"itemizedlist"><ul type=
"disc"><li><p>retrieve the contents of a print queue
</p></li><li><p>pause the print queue
</p></li><li><p>resume a paused print queue
</p></li><li><p>delete a job from the queue
</p></li><li><p>pause a job in the print queue
</p></li><li><p>result a paused print job in the queue
</p></li><li><p>submit a job to the print queue
</p></li></ul></div><p>
1415 Currently there are only two printing back end implementations
1417 </p><div class=
"itemizedlist"><ul type=
"disc"><li><p>a generic set of functions for working with standard UNIX
1418 printing subsystems
</p></li><li><p>a set of CUPS specific functions (this is only enabled if
1419 the CUPS libraries were located at compile time).
</p></li></ul></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2890298"></a>
1421 </h2></div></div><div></div></div><p>
1422 Samba provides periodic caching of the output from the
"lpq command
"
1423 for performance reasons. This cache time is configurable in seconds.
1424 Obviously the longer the cache time the less often smbd will be
1425 required to exec a copy of lpq. However, the accuracy of the print
1426 queue contents displayed to clients will be diminished as well.
1428 The list of currently opened print queue TDB's can be found
1429 be examining the list of tdb_print_db structures ( see print_db_head
1430 in printing.c ). A queue TDB is opened using the wrapper function
1431 printing.c:get_print_db_byname(). The function ensures that smbd
1432 does not open more than MAX_PRINT_DBS_OPEN in an effort to prevent
1433 a large print server from exhausting all available file descriptors.
1434 If the number of open queue TDB's exceeds the MAX_PRINT_DBS_OPEN
1435 limit, smbd falls back to a most recently used algorithm for maintaining
1436 a list of open TDB's.
1438 There are two ways in which a a print job can be entered into
1439 a print queue's TDB. The first is to submit the job from a Windows
1440 client which will insert the job information directly into the TDB.
1441 The second method is to have the print job picked up by executing the
1442 "lpq command
".
1443 </p><pre class=
"programlisting">
1444 /* included from printing.h */
1446 pid_t pid; /* which process launched the job */
1447 int sysjob; /* the system (lp) job number */
1448 int fd; /* file descriptor of open file if open */
1449 time_t starttime; /* when the job started spooling */
1450 int status; /* the status of this job */
1451 size_t size; /* the size of the job so far */
1452 int page_count; /* then number of pages so far */
1453 BOOL spooled; /* has it been sent to the spooler yet? */
1454 BOOL smbjob; /* set if the job is a SMB job */
1455 fstring filename; /* the filename used to spool the file */
1456 fstring jobname; /* the job name given to us by the client */
1457 fstring user; /* the user who started the job */
1458 fstring queuename; /* service number of printer for this job */
1459 NT_DEVICEMODE *nt_devmode;
1462 The current manifestation of the printjob structure contains a field
1463 for the UNIX job id returned from the
"lpq command
" and a Windows job
1464 ID (
32-bit bounded by PRINT_MAX_JOBID). When a print job is returned
1465 by the
"lpq command
" that does not match an existing job in the queue's
1466 TDB, a
32-bit job ID above the
<*vance doesn't know what word is missing here*
> is generating by adding UNIX_JOB_START to
1467 the id reported by lpq.
1469 In order to match a
32-bit Windows jobid onto a
16-bit lanman print job
1470 id, smbd uses an in memory TDB to match the former to a number appropriate
1471 for old lanman clients.
1473 When updating a print queue, smbd will perform the following
1474 steps ( refer to
<tt class=
"filename">print.c:print_queue_update()
</tt> ):
1475 </p><div class=
"orderedlist"><ol type=
"1"><li><p>Check to see if another smbd is currently in
1476 the process of updating the queue contents by checking the pid
1477 stored in
<tt class=
"constant">LOCK/
<i class=
"replaceable"><tt>printer_name
</tt></i></tt>.
1478 If so, then do not update the TDB.
</p></li><li><p>Lock the mutex entry in the TDB and store our own pid.
1479 Check that this succeeded, else fail.
</p></li><li><p>Store the updated time stamp for the new cache
1480 listing
</p></li><li><p>Retrieve the queue listing via
"lpq command
"</p></li><li><pre class=
"programlisting">
1481 foreach job in the queue
1483 if the job is a UNIX job, create a new entry;
1484 if the job has a Windows based jobid, then
1486 Lookup the record by the jobid;
1487 if the lookup failed, then
1488 treat it as a UNIX job;
1490 update the job status only
1492 }
</pre></li><li><p>Delete any jobs in the TDB that are not
1493 in the in the lpq listing
</p></li><li><p>Store the print queue status in the TDB
</p></li><li><p>update the cache time stamp again
</p></li></ol></div><p>
1494 Note that it is the contents of this TDB that is returned to Windows
1495 clients and not the actual listing from the
"lpq command
".
1497 The NT_DEVICEMODE stored as part of the printjob structure is used to
1498 store a pointer to a non-default DeviceMode associated with the print
1499 job. The pointer will be non-null when the client included a Device
1500 Mode in the OpenPrinterEx() call and subsequently submitted a job for
1501 printing on that same handle. If the client did not include a Device
1502 Mode in the OpenPrinterEx() request, the nt_devmode field is NULL
1503 and the job has the printer's device mode associated with it by default.
1505 Only non-default Device Mode are stored with print jobs in the print
1506 queue TDB. Otherwise, the Device Mode is obtained from the printer
1507 object when the client issues a GetJob(level ==
2) request.
1508 </p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2890507"></a>
1509 ChangeID and Client Caching of Printer Information
1510 </h2></div></div><div></div></div><p>
1511 [To be filled in later]
1512 </p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2890520"></a>
1513 Windows NT/
2K Printer Change Notify
1514 </h2></div></div><div></div></div><p>
1515 When working with Windows NT+ clients, it is possible for a
1516 print server to use RPC to send asynchronous change notification
1517 events to clients for certain printer and print job attributes.
1518 This can be useful when the client needs to know that a new
1519 job has been added to the queue for a given printer or that the
1520 driver for a printer has been changed. Note that this is done
1521 entirely orthogonal to cache updates based on a new ChangeID for
1524 The basic set of RPC's used to implement change notification are
1525 </p><div class=
"itemizedlist"><ul type=
"disc"><li><p>RemoteFindFirstPrinterChangeNotifyEx ( RFFPCN )
</p></li><li><p>RemoteFindNextPrinterChangeNotifyEx ( RFNPCN )
</p></li><li><p>FindClosePrinterChangeNotify( FCPCN )
</p></li><li><p>ReplyOpenPrinter
</p></li><li><p>ReplyClosePrinter
</p></li><li><p>RouteRefreshPrinterChangeNotify ( RRPCN )
</p></li></ul></div><p>
1526 One additional RPC is available to a server, but is never used by the
1527 Windows spooler service:
1528 </p><div class=
"itemizedlist"><ul type=
"disc"><li><p>RouteReplyPrinter()
</p></li></ul></div><p>
1529 The opnum for all of these RPC's are defined in include/rpc_spoolss.h
1531 Windows NT print servers use a bizarre method of sending print
1532 notification event to clients. The process of registering a new change
1533 notification handle is as follows. The 'C' is for client and the
1534 'S' is for server. All error conditions have been eliminated.
1535 </p><pre class=
"programlisting">
1536 C: Obtain handle to printer or to the printer
1537 server via the standard OpenPrinterEx() call.
1538 S: Respond with a valid handle to object
1540 C: Send a RFFPCN request with the previously obtained
1541 handle with either (a) set of flags for change events
1542 to monitor, or (b) a PRINTER_NOTIFY_OPTIONS structure
1543 containing the event information to monitor. The windows
1544 spooler has only been observed to use (b).
1545 S: The
<* another missing word*
> opens a new TCP session to the client (thus requiring
1546 all print clients to be CIFS servers as well) and sends
1547 a ReplyOpenPrinter() request to the client.
1548 C: The client responds with a printer handle that can be used to
1549 send event notification messages.
1550 S: The server replies success to the RFFPCN request.
1552 C: The windows spooler follows the RFFPCN with a RFNPCN
1553 request to fetch the current values of all monitored
1555 S: The server replies with an array SPOOL_NOTIFY_INFO_DATA
1556 structures (contained in a SPOOL_NOTIFY_INFO structure).
1558 C: If the change notification handle is ever released by the
1559 client via a FCPCN request, the server sends a ReplyClosePrinter()
1560 request back to the client first. However a request of this
1561 nature from the client is often an indication that the previous
1562 notification event was not marshalled correctly by the server
1563 or a piece of data was wrong.
1564 S: The server closes the internal change notification handle
1565 (POLICY_HND) and does not send any further change notification
1566 events to the client for that printer or job.
1568 The current list of notification events supported by Samba can be
1569 found by examining the internal tables in srv_spoolss_nt.c
1570 </p><div class=
"itemizedlist"><ul type=
"disc"><li><p>printer_notify_table[]
</p></li><li><p>job_notify_table[]
</p></li></ul></div><p>
1571 When an event occurs that could be monitored, smbd sends a message
1572 to itself about the change. The list of events to be transmitted
1573 are queued by the smbd process sending the message to prevent an
1574 overload of TDB usage and the internal message is sent during smbd's
1575 idle loop (refer to printing/notify.c and the functions
1576 send_spoolss_notify2_msg() and print_notify_send_messages() ).
1578 The decision of whether or not the change is to be sent to connected
1579 clients is made by the routine which actually sends the notification.
1580 ( refer to srv_spoolss_nt.c:recieve_notify2_message() ).
1582 Because it possible to receive a listing of multiple changes for
1583 multiple printers, the notification events must be split into
1584 categories by the printer name. This makes it possible to group
1585 multiple change events to be sent in a single RPC according to the
1586 printer handle obtained via a ReplyOpenPrinter().
1588 The actual change notification is performed using the RRPCN request
1589 RPC. This packet contains
1590 </p><div class=
"itemizedlist"><ul type=
"disc"><li><p>the printer handle registered with the
1591 client's spooler on which the change occurred
</p></li><li><p>The change_low value which was sent as part
1592 of the last RFNPCN request from the client
</p></li><li><p>The SPOOL_NOTIFY_INFO container with the event
1593 information
</p></li></ul></div><p>
1594 A
<tt class=
"varname">SPOOL_NOTIFY_INFO
</tt> contains:
1595 </p><div class=
"itemizedlist"><ul type=
"disc"><li><p>the version and flags field are predefined
1596 and should not be changed
</p></li><li><p>The count field is the number of entries
1597 in the SPOOL_NOTIFY_INFO_DATA array
</p></li></ul></div><p>
1598 The
<tt class=
"varname">SPOOL_NOTIFY_INFO_DATA
</tt> entries contain:
1599 </p><div class=
"itemizedlist"><ul type=
"disc"><li><p>The type defines whether or not this event
1600 is for a printer or a print job
</p></li><li><p>The field is the flag identifying the event
</p></li><li><p>the notify_data union contains the new valuie of the
1601 attribute
</p></li><li><p>The enc_type defines the size of the structure for marshalling
1602 and unmarshalling
</p></li><li><p>(a) the id must be
0 for a printer event on a printer handle.
1603 (b) the id must be the job id for an event on a printer job
1604 (c) the id must be the matching number of the printer index used
1605 in the response packet to the RFNPCN when using a print server
1606 handle for notification. Samba currently uses the snum of
1607 the printer for this which can break if the list of services
1608 has been modified since the notification handle was registered.
</p></li><li><p>The size is either (a) the string length in UNICODE for strings,
1609 (b) the size in bytes of the security descriptor, or (c)
0 for
1610 data values.
</p></li></ul></div></div></div><div class=
"chapter" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title"><a name=
"wins"></a>Chapter
12. Samba WINS Internals
</h2></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Gerald
</span> <span class=
"surname">Carter
</span></h3></div></div><div><p class=
"pubdate">October
2002</p></div></div><div></div></div><div class=
"toc"><p><b>Table of Contents
</b></p><dl><dt><a href=
"#id2889988">WINS Failover
</a></dt></dl></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2889988"></a>WINS Failover
</h2></div></div><div></div></div><p>
1611 The current Samba codebase possesses the capability to use groups of WINS
1612 servers that share a common namespace for NetBIOS name registration and
1613 resolution. The formal parameter syntax is
1614 </p><pre class=
"programlisting">
1615 WINS_SERVER_PARAM = SERVER [ SEPARATOR SERVER_LIST ]
1616 WINS_SERVER_PARAM =
"wins server
"
1618 ADDR = ip_addr | fqdn
1620 SEPARATOR = comma | \s+
1621 SERVER_LIST = SERVER [ SEPARATOR SERVER_LIST ]
1623 A simple example of a valid wins server setting is
1624 </p><pre class=
"programlisting">
1626 wins server =
192.168.1.2 192.168.1.3
1628 In the event that no TAG is defined in for a SERVER in the list, smbd assigns a default
1629 TAG of
"*
". A TAG is used to group servers of a shared NetBIOS namespace together. Upon
1630 startup, nmbd will attempt to register the netbios name value with one server in each
1633 An example using tags to group WINS servers together is show here. Note that the use of
1634 interface names in the tags is only by convention and is not a technical requirement.
1635 </p><pre class=
"programlisting">
1637 wins server =
192.168.1.2:eth0
192.168.1.3:eth0
192.168.2.2:eth1
1639 Using this configuration, nmbd would attempt to register the server's NetBIOS name
1640 with one WINS server in each group. Because the
"eth0
" group has two servers, the
1641 second server would only be used when a registration (or resolution) request to
1642 the first server in that group timed out.
1644 NetBIOS name resolution follows a similar pattern as name registration. When resolving
1645 a NetBIOS name via WINS, smbd and other Samba programs will attempt to query a single WINS
1646 server in a tagged group until either a positive response is obtained at least once or
1647 until a server from every tagged group has responded negatively to the name query request.
1648 If a timeout occurs when querying a specific WINS server, that server is marked as down to
1649 prevent further timeouts and the next server in the WINS group is contacted. Once marked as
1650 dead, Samba will not attempt to contact that server for name registration/resolution queries
1651 for a period of
10 minutes.
1652 </p></div></div><div class=
"chapter" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title"><a name=
"sam"></a>Chapter
13. The Upcoming SAM System
</h2></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Andrew
</span> <span class=
"surname">Bartlett
</span></h3></div></div><div><p class=
"pubdate">1 October
2002</p></div></div><div></div></div><div class=
"toc"><p><b>Table of Contents
</b></p><dl><dt><a href=
"#id2889789">Security in the 'new SAM'
</a></dt><dt><a href=
"#id2891316">Standalone from UNIX
</a></dt><dt><a href=
"#id2891349">Handles and Races in the new SAM
</a></dt><dt><a href=
"#id2891418">Layers
</a></dt><dd><dl><dt><a href=
"#id2891425">Application
</a></dt><dt><a href=
"#id2891441">SAM Interface
</a></dt><dt><a href=
"#id2891468">SAM Modules
</a></dt></dl></dd><dt><a href=
"#id2891490">SAM Modules
</a></dt><dd><dl><dt><a href=
"#id2891497">Special Module: sam_passdb
</a></dt><dt><a href=
"#id2891516">sam_ads
</a></dt></dl></dd><dt><a href=
"#id2891555">Memory Management
</a></dt><dt><a href=
"#id2891645">Testing
</a></dt></dl></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2889789"></a>Security in the 'new SAM'
</h2></div></div><div></div></div><p>One of the biggest problems with passdb is it's implementation of
1653 'security'. Access control is on a 'are you root at the moment' basis,
1654 and it has no concept of NT ACLs. Things like ldapsam had to add
1655 'magic' 'are you root' checks.
</p><p>We took this very seriously when we started work, and the new structure
1656 is designed with this in mind, from the ground up. Each call to the SAM
1657 has a NT_TOKEN and (if relevant) an 'access desired'. This is either
1658 provided as a parameter, or implicitly supplied by the object being
1660 For example, when you call
1661 </p><pre class=
"programlisting">
1662 NTSTATUS sam_get_account_by_name(const SAM_CONTEXT *context, const
1663 NT_USER_TOKEN *access_token, uint32 access_desired, const char *domain,
1664 const char *name, SAM_ACCOUNT_HANDLE **account)
1666 The context can be NULL (and is used to allow import/export by setting
1667 up
2 contexts, and allowing calls on both simultaneously)
1669 The access token *must* be specified. Normally the user's token out of
1670 current_user, this can also be a global 'system' context.
1672 The access desired is as per the ACL, for passing to the seaccess stuff.
1674 The domain/username are standard. Even if we only have one domain,
1675 keeping this ensures that we don't get 'unqualified' usernames (same
1676 problem as we had with unqualified SIDs).
1678 We return a 'handle'. This is opaque to the rest of Samba, but is
1679 operated on by get/set routines, all of which return NTSTATUS.
1681 The access checking is done by the SAM module. The reason it is not
1682 done 'above' the interface is to ensure a 'choke point'. I put a lot of
1683 effort into the auth subsystem to ensure we never 'accidentally' forgot
1684 to check for null passwords, missed a restriction etc. I intend the SAM
1685 to be written with the same caution.
1687 The reason the access checking is not handled by the interface itself is
1688 due to the different implementations it make take on. For example, on
1689 ADS, you cannot set a password over a non-SSL connection. Other
1690 backends may have similar requirements - we need to leave this policy up
1691 to the modules. They will naturally have access to 'helper' procedures
1692 and good examples to avoid mishaps.
1694 (Furthermore, some backends my actually chose to push the whole ACL
1695 issue to the remote server, and - assuming ldap for this example - bind
1696 as the user directly)
1698 Each returned handle has an internal 'access permitted', which allows
1699 the 'get' and 'set' routines to return 'ACCESS_DENIED' for things that
1700 were not able to be retrieved from the backend. This removes the need
1701 to specify the NT_TOKEN on every operation, and allows for 'object not
1702 present' to be easily distinguished from 'access denied'.
1704 When you 'set' an object (calling sam_update_account) the internal
1705 details are again used. Each change that has been made to the object
1706 has been flagged, so as to avoid race conditions (on unmodified
1707 components) and to avoid violating any extra ACL requirements on the
1708 actual data store (like the LDAP server).
1710 Finally, we have generic get_sec_desc() and set_sec_desc() routines to
1711 allow external ACL manipulation. These do lookups based on SID.
1712 </p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2891316"></a>Standalone from UNIX
</h2></div></div><div></div></div><p>
1713 One of the primary tenants of the 'new SAM' is that it would not attempt
1714 to deal with 'what unix id for that'. This would be left to the 'SMS'
1715 (Sid Mapping System') or SID farm, and probably administered via
1716 winbind. We have had constructive discussion on how 'basic' unix
1717 accounts like 'root' would be handled, and we think this can work.
1718 Accounts not preexisting in unix would be served up via winbind.
1720 This is an *optional* part, and my preferred end-game. We have a fare
1721 way to go before things like winbind up to it however.
1722 </p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2891349"></a>Handles and Races in the new SAM
</h2></div></div><div></div></div><p>
1723 One of the things that the 'new SAM' work has tried to face is both
1724 compatibility with existing code, and a closer alignment to the SAMR
1725 interface. I consider SAMR to be a 'primary customer' to the this work,
1726 because if we get alignment with that wrong, things get more, rather
1727 than less complex. Also, most other parts of Samba are much more
1728 flexible with what they can allow.
1730 In any case, that was a decision taken as to how the general design
1731 would progress. BTW, my understanding of SAMR may be completely flawed.
1733 One of the most race-prone areas of the new code is the conflicting
1734 update problem. We have taken two approaches:
1735 </p><div class=
"itemizedlist"><ul type=
"disc"><li><p>'Not conflicting' conflicts. Due to the way usrmgr operates, it will
1736 open a user, display all the properties and *save* them all, even if you
1739 For this, see what I've done in rpc_server/srv_samr_util.c. I intend
1740 to take this one step further, and operate on the 'handle' that the
1741 values were read from. This should mean that we only update things that
1742 have *really* changed.
1744 'conflicting' updates: Currently we don't deal with this (in passdb
1745 or the new sam stuff), but the design is sufficiently flexible to 'deny'
1746 a second update. I don't foresee locking records however.
1747 </p></li></ul></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2891418"></a>Layers
</h2></div></div><div></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2891425"></a>Application
</h3></div></div><div></div></div><p>
1748 This is where smbd, samtest and whatever end-user replacement we have
1749 for pdbedit sits. They use only the SAM interface, and do not get
1750 'special knowledge' of what is below them.
1751 </p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2891441"></a>SAM Interface
</h3></div></div><div></div></div><p>
1752 This level 'owns' the various handle structures, the get/set routines on
1753 those structures and provides the public interface. The application
1754 layer may initialize a 'context' to be passed to all interface routines,
1755 else a default, self-initialising context will be supplied. This layser
1756 finds the appropriate backend module for the task, and tries very hard
1757 not to need to much 'knowledge'. It should just provide the required
1758 abstraction to the modules below, and arrange for their initial loading.
1760 We could possibly add ACL checking at this layer, to avoid discrepancies
1761 in implementation modules.
1762 </p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2891468"></a>SAM Modules
</h3></div></div><div></div></div><p>
1763 These do not communicate with the application directly, only by setting
1764 values in the handles, and receiving requests from the interface. These
1765 modules are responsible for translating values from the handle's
1766 .private into (say) an LDAP modification list. The module is expected
1767 to 'know' things like it's own domain SID, domain name, and any other
1768 state attached to the SAM. Simpler modules may call back to some helper
1770 </p></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2891490"></a>SAM Modules
</h2></div></div><div></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2891497"></a>Special Module: sam_passdb
</h3></div></div><div></div></div><p>
1771 In order for there to be a smooth transition, kai is writing a module
1772 that reads existing passdb backends, and translates them into SAM
1773 replies. (Also pulling data from the account policy DB etc). We also
1774 intend to write a module that does the reverse - gives the SAM a passdb
1776 </p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2891516"></a>sam_ads
</h3></div></div><div></div></div><p>
1777 This is the first of the SAM modules to be committed to the tree -
1778 mainly because I needed to coordinate work with metze (who authored most
1779 of it). This module aims to use Samba's libads code to provide an
1780 Active Directory LDAP client, suitable for use on a mixed-mode DC.
1781 While it is currently being tested against Win2k servers (with a
1782 password in the smb.conf file) it is expected to eventually use a
1783 (possibly modified) OpenLDAP server. We hope that this will assist in
1784 the construction of an Samba AD DC.
1786 We also intend to construct a Samba
2.2/
3.0 compatible ldap module,
1787 again using libads code.
1788 </p></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2891555"></a>Memory Management
</h2></div></div><div></div></div><p>
1789 The 'new SAM' development effort also concerned itself with getting a
1790 sane implementation of memory management. It was decided that we would
1791 be (as much as possible) talloc based, using an 'internal talloc
1792 context' on many objects. That is, the creation of an object would
1793 initiate it's own internal talloc context, and this would be used for
1794 all operations on that object. Much of this is already implemented in
1795 passdb. Also, like passdb, it will be possible to specify that some
1796 object actually be created on a specified context.
1798 Memory management is important here because the APIs in the 'new SAM' do
1799 not use 'pdb_init()' or an equivalent. They always allocate new
1800 objects. Enumeration's are slightly different, and occur on a supplied
1801 context that 'owns' the entire list, rather than per-element. (the
1802 enumeration functions return an array of all elements - not full handles
1803 just basic (and public) info) Likewise for things that fill in a char
1805 </p><p>For example:
</p><pre class=
"programlisting">
1806 NTSTATUS sam_lookup_sid(const SAM_CONTEXT *context, const NT_USER_TOKEN
1807 *access_token, TALLOC_CTX *mem_ctx, const DOM_SID *sid, char **name,
1809 </pre><p>Takes a context to allocate the 'name' on, while:
</p><pre class=
"programlisting">
1810 NTSTATUS sam_get_account_by_sid(const SAM_CONTEXT *context, const
1811 NT_USER_TOKEN *access_token, uint32 access_desired, const DOM_SID
1812 *accountsid, SAM_ACCOUNT_HANDLE **account)
1813 </pre><p>Allocates a handle and stores the allocation context on that handle.
</p><p>I think that the following:
</p><pre class=
"programlisting">
1814 NTSTATUS sam_enum_accounts(const SAM_CONTEXT *context, const
1815 NT_USER_TOKEN *access_token, const DOM_SID *domainsid, uint16 acct_ctrl,
1816 int32 *account_count, SAM_ACCOUNT_ENUM **accounts)
1817 </pre></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2891645"></a>Testing
</h2></div></div><div></div></div><p>
1818 Testing is vital in any piece of software, and Samba is certainly no
1819 exception. In designing this new subsystem, we have taken care to ensure
1820 it is easily tested, independent of outside protocols.
1822 To this end, Jelmer has constructed 'samtest'.
1824 This utility (see torture/samtest.c) is structured like rpcclient, but
1825 instead operates on the SAM subsystem. It creates a 'custom' SAM
1826 context, that may be distinct from the default values used by the rest
1827 of the system, and can load a separate configuration file.
1829 A small number of commands are currently implemented, but these have
1830 already proved vital in testing. I expect SAM module authors will find
1831 it particularly valuable.
1832 </p><p>Example useage:
</p><p><tt class=
"prompt">$
</tt> <b class=
"command">bin/samtest
</b></p><pre class=
"programlisting">
1833 > context ads:ldap://
192.168.1.96
1835 (this loads a new context, using the new ADS module. The parameter is
1836 the 'location' of the ldap server)
1837 </p><pre class=
"programlisting">
1838 > lookup_name DOMAIN abartlet
1842 Because the 'new SAM' is NT ACL based, there will be a command to
1843 specify an arbitrary NT ACL, but for now it uses 'system' by default.
1844 </p></div></div><div class=
"chapter" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title"><a name=
"pwencrypt"></a>Chapter
14. LanMan and NT Password Encryption
</h2></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Jeremy
</span> <span class=
"surname">Allison
</span></h3><div class=
"affiliation"><span class=
"orgname">Samba Team
<br></span><div class=
"address"><p><br>
1845 <tt class=
"email"><<a href=
"mailto:samba@samba.org">samba@samba.org
</a>></tt><br>
1846 </p></div></div></div></div><div><p class=
"pubdate">19 Apr
1999</p></div></div><div></div></div><div class=
"toc"><p><b>Table of Contents
</b></p><dl><dt><a href=
"#id2892285">Introduction
</a></dt><dt><a href=
"#id2892310">How does it work?
</a></dt><dt><a href=
"#id2891197">The smbpasswd file
</a></dt></dl></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2892285"></a>Introduction
</h2></div></div><div></div></div><p>With the development of LanManager and Windows NT
1847 compatible password encryption for Samba, it is now able
1848 to validate user connections in exactly the same way as
1849 a LanManager or Windows NT server.
</p><p>This document describes how the SMB password encryption
1850 algorithm works and what issues there are in choosing whether
1851 you want to use it. You should read it carefully, especially
1852 the part about security and the
"PROS and CONS
" section.
</p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2892310"></a>How does it work?
</h2></div></div><div></div></div><p>LanManager encryption is somewhat similar to UNIX
1853 password encryption. The server uses a file containing a
1854 hashed value of a user's password. This is created by taking
1855 the user's plaintext password, capitalising it, and either
1856 truncating to
14 bytes or padding to
14 bytes with null bytes.
1857 This
14 byte value is used as two
56 bit DES keys to encrypt
1858 a 'magic' eight byte value, forming a
16 byte value which is
1859 stored by the server and client. Let this value be known as
1860 the
"hashed password
".
</p><p>Windows NT encryption is a higher quality mechanism,
1861 consisting of doing an MD4 hash on a Unicode version of the user's
1862 password. This also produces a
16 byte hash value that is
1863 non-reversible.
</p><p>When a client (LanManager, Windows for WorkGroups, Windows
1864 95 or Windows NT) wishes to mount a Samba drive (or use a Samba
1865 resource), it first requests a connection and negotiates the
1866 protocol that the client and server will use. In the reply to this
1867 request the Samba server generates and appends an
8 byte, random
1868 value - this is stored in the Samba server after the reply is sent
1869 and is known as the
"challenge
". The challenge is different for
1870 every client connection.
</p><p>The client then uses the hashed password (
16 byte values
1871 described above), appended with
5 null bytes, as three
56 bit
1872 DES keys, each of which is used to encrypt the challenge
8 byte
1873 value, forming a
24 byte value known as the
"response
".
</p><p>In the SMB call SMBsessionsetupX (when user level security
1874 is selected) or the call SMBtconX (when share level security is
1875 selected), the
24 byte response is returned by the client to the
1876 Samba server. For Windows NT protocol levels the above calculation
1877 is done on both hashes of the user's password and both responses are
1878 returned in the SMB call, giving two
24 byte values.
</p><p>The Samba server then reproduces the above calculation, using
1879 its own stored value of the
16 byte hashed password (read from the
1880 <tt class=
"filename">smbpasswd
</tt> file - described later) and the challenge
1881 value that it kept from the negotiate protocol reply. It then checks
1882 to see if the
24 byte value it calculates matches the
24 byte value
1883 returned to it from the client.
</p><p>If these values match exactly, then the client knew the
1884 correct password (or the
16 byte hashed value - see security note
1885 below) and is thus allowed access. If not, then the client did not
1886 know the correct password and is denied access.
</p><p>Note that the Samba server never knows or stores the cleartext
1887 of the user's password - just the
16 byte hashed values derived from
1888 it. Also note that the cleartext password or
16 byte hashed values
1889 are never transmitted over the network - thus increasing security.
</p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2891197"></a>The smbpasswd file
</h2></div></div><div></div></div><a name=
"SMBPASSWDFILEFORMAT"></a><p>In order for Samba to participate in the above protocol
1890 it must be able to look up the
16 byte hashed values given a user name.
1891 Unfortunately, as the UNIX password value is also a one way hash
1892 function (ie. it is impossible to retrieve the cleartext of the user's
1893 password given the UNIX hash of it), a separate password file
1894 containing this
16 byte value must be kept. To minimise problems with
1895 these two password files, getting out of sync, the UNIX
<tt class=
"filename">
1896 /etc/passwd
</tt> and the
<tt class=
"filename">smbpasswd
</tt> file,
1897 a utility,
<b class=
"command">mksmbpasswd.sh
</b>, is provided to generate
1898 a smbpasswd file from a UNIX
<tt class=
"filename">/etc/passwd
</tt> file.
1899 </p><p>To generate the smbpasswd file from your
<tt class=
"filename">/etc/passwd
1900 </tt> file use the following command:
</p><p><tt class=
"prompt">$
</tt><b class=
"userinput"><tt>cat /etc/passwd | mksmbpasswd.sh
1901 > /usr/local/samba/private/smbpasswd
</tt></b></p><p>If you are running on a system that uses NIS, use
</p><p><tt class=
"prompt">$
</tt><b class=
"userinput"><tt>ypcat passwd | mksmbpasswd.sh
1902 > /usr/local/samba/private/smbpasswd
</tt></b></p><p>The
<b class=
"command">mksmbpasswd.sh
</b> program is found in
1903 the Samba source directory. By default, the smbpasswd file is
1904 stored in :
</p><p><tt class=
"filename">/usr/local/samba/private/smbpasswd
</tt></p><p>The owner of the
<tt class=
"filename">/usr/local/samba/private/
</tt>
1905 directory should be set to root, and the permissions on it should
1906 be set to
0500 (
<b class=
"command">chmod
500 /usr/local/samba/private
</b>).
1907 </p><p>Likewise, the smbpasswd file inside the private directory should
1908 be owned by root and the permissions on is should be set to
0600
1909 (
<b class=
"command">chmod
600 smbpasswd
</b>).
</p><p>The format of the smbpasswd file is (The line has been
1910 wrapped here. It should appear as one entry per line in
1911 your smbpasswd file.)
</p><pre class=
"programlisting">
1912 username:uid:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:
1913 [Account type]:LCT-
<last-change-time
>:Long name
1914 </pre><p>Although only the
<i class=
"replaceable"><tt>username
</tt></i>,
1915 <i class=
"replaceable"><tt>uid
</tt></i>,
<i class=
"replaceable"><tt>
1916 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
</tt></i>,
1917 [
<i class=
"replaceable"><tt>Account type
</tt></i>] and
<i class=
"replaceable"><tt>
1918 last-change-time
</tt></i> sections are significant
1919 and are looked at in the Samba code.
</p><p>It is
<span class=
"emphasis"><em>VITALLY
</em></span> important that there by
32
1920 'X' characters between the two ':' characters in the XXX sections -
1921 the smbpasswd and Samba code will fail to validate any entries that
1922 do not have
32 characters between ':' characters. The first XXX
1923 section is for the Lanman password hash, the second is for the
1924 Windows NT version.
</p><p>When the password file is created all users have password entries
1925 consisting of
32 'X' characters. By default this disallows any access
1926 as this user. When a user has a password set, the 'X' characters change
1927 to
32 ascii hexadecimal digits (
0-
9, A-F). These are an ascii
1928 representation of the
16 byte hashed value of a user's password.
</p><p>To set a user to have no password (not recommended), edit the file
1929 using vi, and replace the first
11 characters with the ascii text
1930 <tt class=
"constant">"NO PASSWORD
"</tt> (minus the quotes).
</p><p>For example, to clear the password for user bob, his smbpasswd file
1931 entry would look like :
</p><pre class=
"programlisting">
1932 bob:
100:NO PASSWORDXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:
1933 [U ]:LCT-
00000000:Bob's full name:/bobhome:/bobshell
1934 </pre><p>If you are allowing users to use the smbpasswd command to set
1935 their own passwords, you may want to give users NO PASSWORD initially
1936 so they do not have to enter a previous password when changing to their
1937 new password (not recommended). In order for you to allow this the
1938 <b class=
"command">smbpasswd
</b> program must be able to connect to the
1939 <b class=
"command">smbd
</b> daemon as that user with no password. Enable this
1940 by adding the line :
</p><p><b class=
"command">null passwords = yes
</b></p><p>to the [global] section of the smb.conf file (this is why
1941 the above scenario is not recommended). Preferably, allocate your
1942 users a default password to begin with, so you do not have
1943 to enable this on your server.
</p><p><span class=
"emphasis"><em>Note :
</em></span>This file should be protected very
1944 carefully. Anyone with access to this file can (with enough knowledge of
1945 the protocols) gain access to your SMB server. The file is thus more
1946 sensitive than a normal unix
<tt class=
"filename">/etc/passwd
</tt> file.
</p></div></div><div class=
"chapter" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title"><a name=
"modules"></a>Chapter
15. Modules
</h2></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Jelmer
</span> <span class=
"surname">Vernooij
</span></h3><div class=
"affiliation"><span class=
"orgname">Samba Team
<br></span><div class=
"address"><p><tt class=
"email"><<a href=
"mailto:jelmer@samba.org">jelmer@samba.org
</a>></tt></p></div></div></div></div><div><p class=
"pubdate"> 19 March
2003 </p></div></div><div></div></div><div class=
"toc"><p><b>Table of Contents
</b></p><dl><dt><a href=
"#id2892236">Advantages
</a></dt><dt><a href=
"#id2893136">Loading modules
</a></dt><dd><dl><dt><a href=
"#id2893169">Static modules
</a></dt><dt><a href=
"#id2894111">Shared modules
</a></dt></dl></dd><dt><a href=
"#id2894139">Writing modules
</a></dt><dd><dl><dt><a href=
"#id2894200">Static/Shared selection in configure.in
</a></dt></dl></dd></dl></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2892236"></a>Advantages
</h2></div></div><div></div></div><p>
1947 The new modules system has the following advantages:
1948 </p><table class=
"simplelist" border=
"0" summary=
"Simple list"><tr><td>Transparent loading of static and shared modules (no need
1949 for a subsystem to know about modules)
</td></tr><tr><td>Simple selection between shared and static modules at configure time
</td></tr><tr><td>"preload modules
" option for increasing performance for stable modules
</td></tr><tr><td>No nasty #define stuff anymore
</td></tr><tr><td>All backends are available as plugin now (including pdb_ldap and pdb_tdb)
</td></tr></table></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2893136"></a>Loading modules
</h2></div></div><div></div></div><p>
1950 Some subsystems in samba use different backends. These backends can be
1951 either statically linked in to samba or available as a plugin. A subsystem
1952 should have a function that allows a module to register itself. For example,
1953 the passdb subsystem has:
1954 </p><pre class=
"programlisting">
1955 NTSTATUS smb_register_passdb(int version, const char *name, pdb_init_function init);
1957 This function will be called by the initialisation function of the module to
1959 </p><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2893169"></a>Static modules
</h3></div></div><div></div></div><p>
1960 The modules system compiles a list of initialisation functions for the
1961 static modules of each subsystem. This is a define. For example,
1962 it is here currently (from
<tt class=
"filename">include/config.h
</tt>):
1963 </p><pre class=
"programlisting">
1964 /* Static init functions */
1965 #define static_init_pdb { pdb_mysql_init(); pdb_ldap_init(); pdb_smbpasswd_init(); pdb_tdbsam_init(); pdb_guest_init();}
1967 These functions should be called before the subsystem is used. That
1968 should be done when the subsystem is initialised or first used.
1969 </p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2894111"></a>Shared modules
</h3></div></div><div></div></div><p>
1970 If a subsystem needs a certain backend, it should check if it has
1971 already been registered. If the backend hasn't been registered already,
1972 the subsystem should call smb_probe_module(char *subsystem, char *backend).
1973 This function tries to load the correct module from a certain path
1974 ($LIBDIR/subsystem/backend.so). If the first character in 'backend'
1975 is a slash, smb_probe_module() tries to load the module from the
1976 absolute path specified in 'backend'.
1977 </p><p>After smb_probe_module() has been executed, the subsystem
1978 should check again if the module has been registered.
1979 </p></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2894139"></a>Writing modules
</h2></div></div><div></div></div><p>
1980 Each module has an initialisation function. For modules that are
1981 included with samba this name is '
<i class=
"replaceable"><tt>subsystem
</tt></i>_
<i class=
"replaceable"><tt>backend
</tt></i>_init'. For external modules (that will never be built-in, but only available as a module) this name is always 'init_module'. (In the case of modules included with samba, the configure system will add a #define subsystem_backend_init() init_module()).
1982 The prototype for these functions is:
1983 </p><pre class=
"programlisting">
1984 NTSTATUS init_module(void);
1985 </pre><p>This function should call one or more
1986 registration functions. The function should return NT_STATUS_OK on success and
1987 NT_STATUS_UNSUCCESSFUL or a more useful nt error code on failure.
</p><p>For example, pdb_ldap_init() contains:
</p><pre class=
"programlisting">
1988 NTSTATUS pdb_ldap_init(void)
1990 smb_register_passdb(PASSDB_INTERFACE_VERSION,
"ldapsam
", pdb_init_ldapsam);
1991 smb_register_passdb(PASSDB_INTERFACE_VERSION,
"ldapsam_nua
", pdb_init_ldapsam_nua);
1992 return NT_STATUS_OK;
1994 </pre><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2894200"></a>Static/Shared selection in configure.in
</h3></div></div><div></div></div><p>
1995 Some macros in configure.in generate the various defines and substs that
1996 are necessary for the system to work correct. All modules that should
1997 be built by default have to be added to the variable 'default_modules'.
1998 For example, if ldap is found, pdb_ldap is added to this variable.
2000 On the bottom of configure.in, SMB_MODULE() should be called
2001 for each module and SMB_SUBSYSTEM() for each subsystem.
2002 </p><p>Syntax:
</p><pre class=
"programlisting">
2003 SMB_MODULE(
<i class=
"replaceable"><tt>subsystem
</tt></i>_
<i class=
"replaceable"><tt>backend
</tt></i>,
<i class=
"replaceable"><tt>object files
</tt></i>,
<i class=
"replaceable"><tt>plugin name
</tt></i>,
<i class=
"replaceable"><tt>subsystem name
</tt></i>,
<i class=
"replaceable"><tt>static_action
</tt></i>,
<i class=
"replaceable"><tt>shared_action
</tt></i>)
2004 SMB_SUBSYSTEM(
<i class=
"replaceable"><tt>subsystem
</tt></i>)
2005 </pre><p>Also, make sure to add the correct directives to
2006 <tt class=
"filename">Makefile.in
</tt>.
<i class=
"replaceable"><tt>@SUBSYSTEM_STATIC@
</tt></i>
2007 will be replaced with a list of objects files of the modules that need to
2008 be linked in statically.
<i class=
"replaceable"><tt>@SUBSYSTEM_MODULES@
</tt></i> will
2009 be replaced with the names of the plugins to build.
2010 </p><p>You must make sure all .c files that contain defines that can
2011 be changed by ./configure are rebuilded in the 'modules_clean' make target.
2012 Practically, this means all c files that contain
<b class=
"command">static_init_subsystem;
</b> calls need to be rebuilded.
2013 </p></div></div></div><div class=
"chapter" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title"><a name=
"rpc-plugin"></a>Chapter
16. RPC Pluggable Modules
</h2></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Anthony
</span> <span class=
"surname">Liguori
</span></h3><div class=
"affiliation"><span class=
"orgname">IBM
<br></span><div class=
"address"><p><tt class=
"email"><<a href=
"mailto:aliguor@us.ibm.com">aliguor@us.ibm.com
</a>></tt></p></div></div></div></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Jelmer
</span> <span class=
"surname">Vernooij
</span></h3><div class=
"affiliation"><span class=
"orgname">Samba Team
<br></span><div class=
"address"><p><tt class=
"email"><<a href=
"mailto:jelmer@samba.org">jelmer@samba.org
</a>></tt></p></div></div></div></div><div><p class=
"pubdate">January
2003</p></div></div><div></div></div><div class=
"toc"><p><b>Table of Contents
</b></p><dl><dt><a href=
"#id2892904">About
</a></dt><dt><a href=
"#id2892923">General Overview
</a></dt></dl></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2892904"></a>About
</h2></div></div><div></div></div><p>
2014 This document describes how to make use the new RPC Pluggable Modules features
2015 of Samba
3.0. This architecture was added to increase the maintainability of
2016 Samba allowing RPC Pipes to be worked on separately from the main CVS branch.
2017 The RPM architecture will also allow third-party vendors to add functionality
2018 to Samba through plug-ins.
2019 </p></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2892923"></a>General Overview
</h2></div></div><div></div></div><p>
2020 When an RPC call is sent to smbd, smbd tries to load a shared library by the
2021 name
<tt class=
"filename">librpc_
<pipename
>.so
</tt> to handle the call if
2022 it doesn't know how to handle the call internally. For instance, LSA calls
2023 are handled by
<tt class=
"filename">librpc_lsass.so
</tt>..
2024 These shared libraries should be located in the
<tt class=
"filename"><sambaroot
>/lib/rpc
</tt>. smbd then attempts to call the init_module function within
2025 the shared library. Check the chapter on modules for more information.
2027 In the init_module function, the library should call
2028 rpc_pipe_register_commands(). This function takes the following arguments:
2029 </p><pre class=
"programlisting">
2030 NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *srv,
2031 const struct api_struct *cmds, int size);
2032 </pre><div class=
"variablelist"><dl><dt><span class=
"term">version
</span></dt><dd><p>Version number of the RPC interface. Use the define
<span class=
"emphasis"><em>SMB_RPC_INTERFACE_VERSION
</em></span> for this
2033 argument.
</p></dd><dt><span class=
"term">clnt
</span></dt><dd><p>the Client name of the named pipe
</p></dd><dt><span class=
"term">srv
</span></dt><dd><p>the Server name of the named pipe
</p></dd><dt><span class=
"term">cmds
</span></dt><dd><p>a list of api_structs that map RPC ordinal numbers to function calls
</p></dd><dt><span class=
"term">size
</span></dt><dd><p>the number of api_structs contained in cmds
</p></dd></dl></div><p>
2034 See rpc_server/srv_reg.c and rpc_server/srv_reg_nt.c for a small example of
2035 how to use this library.
2036 </p></div></div><div class=
"chapter" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title"><a name=
"vfs"></a>Chapter
17. VFS Modules
</h2></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Alexander
</span> <span class=
"surname">Bokovoy
</span></h3><div class=
"affiliation"><div class=
"address"><p><tt class=
"email"><<a href=
"mailto:ab@samba.org">ab@samba.org
</a>></tt></p></div></div></div></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Stefan
</span> <span class=
"surname">Metzmacher
</span></h3><div class=
"affiliation"><div class=
"address"><p><tt class=
"email"><<a href=
"mailto:metze@metzemix.de">metze@metzemix.de
</a>></tt></p></div></div></div></div><div><p class=
"pubdate"> 27 May
2003 </p></div></div><div></div></div><div class=
"toc"><p><b>Table of Contents
</b></p><dl><dt><a href=
"#id2895215">The Samba (Posix) VFS layer
</a></dt><dd><dl><dt><a href=
"#id2895223">The general interface
</a></dt><dt><a href=
"#id2895338">Possible VFS operation layers
</a></dt></dl></dd><dt><a href=
"#id2895409">The Interaction between the Samba VFS subsystem and the modules
</a></dt><dd><dl><dt><a href=
"#id2895418">Initialization and registration
</a></dt><dt><a href=
"#id2895609">How the Modules handle per connection data
</a></dt></dl></dd><dt><a href=
"#id2895852">Upgrading to the New VFS Interface
</a></dt><dd><dl><dt><a href=
"#id2895860">Upgrading from
2.2.* and
3.0aplha modules
</a></dt></dl></dd><dt><a href=
"#id2896401">Some Notes
</a></dt><dd><dl><dt><a href=
"#id2896408">Implement TRANSPARENT functions
</a></dt><dt><a href=
"#id2896432">Implement OPAQUE functions
</a></dt></dl></dd></dl></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2895215"></a>The Samba (Posix) VFS layer
</h2></div></div><div></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2895223"></a>The general interface
</h3></div></div><div></div></div><p>
2037 Each VFS operation has a vfs_op_type, a function pointer and a handle pointer in the
2038 struct vfs_ops and tree macros to make it easier to call the operations.
2039 (Take a look at
<tt class=
"filename">include/vfs.h
</tt> and
<tt class=
"filename">include/vfs_macros.h
</tt>.)
2040 </p><pre class=
"programlisting">
2041 typedef enum _vfs_op_type {
2042 SMB_VFS_OP_NOOP = -
1,
2046 /* File operations */
2053 SMB_VFS_OP_SENDFILE,
2059 </pre><p>This struct contains the function and handle pointers for all operations.
</p><pre class=
"programlisting">
2061 struct vfs_fn_pointers {
2064 /* File operations */
2066 int (*open)(struct vfs_handle_struct *handle,
2067 struct connection_struct *conn,
2068 const char *fname, int flags, mode_t mode);
2069 int (*close)(struct vfs_handle_struct *handle,
2070 struct files_struct *fsp, int fd);
2071 ssize_t (*read)(struct vfs_handle_struct *handle,
2072 struct files_struct *fsp, int fd, void *data, size_t n);
2073 ssize_t (*write)(struct vfs_handle_struct *handle,
2074 struct files_struct *fsp, int fd,
2075 const void *data, size_t n);
2076 SMB_OFF_T (*lseek)(struct vfs_handle_struct *handle,
2077 struct files_struct *fsp, int fd,
2078 SMB_OFF_T offset, int whence);
2079 ssize_t (*sendfile)(struct vfs_handle_struct *handle,
2080 int tofd, files_struct *fsp, int fromfd,
2081 const DATA_BLOB *header, SMB_OFF_T offset, size_t count);
2086 struct vfs_handles_pointers {
2089 /* File operations */
2091 struct vfs_handle_struct *open;
2092 struct vfs_handle_struct *close;
2093 struct vfs_handle_struct *read;
2094 struct vfs_handle_struct *write;
2095 struct vfs_handle_struct *lseek;
2096 struct vfs_handle_struct *sendfile;
2102 This macros SHOULD be used to call any vfs operation.
2103 DO NOT ACCESS conn-
>vfs.ops.* directly !!!
2104 </p><pre class=
"programlisting">
2107 /* File operations */
2108 #define SMB_VFS_OPEN(conn, fname, flags, mode) \
2109 ((conn)-
>vfs.ops.open((conn)-
>vfs.handles.open,\
2110 (conn), (fname), (flags), (mode)))
2111 #define SMB_VFS_CLOSE(fsp, fd) \
2112 ((fsp)-
>conn-
>vfs.ops.close(\
2113 (fsp)-
>conn-
>vfs.handles.close, (fsp), (fd)))
2114 #define SMB_VFS_READ(fsp, fd, data, n) \
2115 ((fsp)-
>conn-
>vfs.ops.read(\
2116 (fsp)-
>conn-
>vfs.handles.read,\
2117 (fsp), (fd), (data), (n)))
2118 #define SMB_VFS_WRITE(fsp, fd, data, n) \
2119 ((fsp)-
>conn-
>vfs.ops.write(\
2120 (fsp)-
>conn-
>vfs.handles.write,\
2121 (fsp), (fd), (data), (n)))
2122 #define SMB_VFS_LSEEK(fsp, fd, offset, whence) \
2123 ((fsp)-
>conn-
>vfs.ops.lseek(\
2124 (fsp)-
>conn-
>vfs.handles.lseek,\
2125 (fsp), (fd), (offset), (whence)))
2126 #define SMB_VFS_SENDFILE(tofd, fsp, fromfd, header, offset, count) \
2127 ((fsp)-
>conn-
>vfs.ops.sendfile(\
2128 (fsp)-
>conn-
>vfs.handles.sendfile,\
2129 (tofd), (fsp), (fromfd), (header), (offset), (count)))
2132 </pre></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2895338"></a>Possible VFS operation layers
</h3></div></div><div></div></div><p>
2133 These values are used by the VFS subsystem when building the conn-
>vfs
2134 and conn-
>vfs_opaque structs for a connection with multiple VFS modules.
2135 Internally, Samba differentiates only opaque and transparent layers at this process.
2136 Other types are used for providing better diagnosing facilities.
2138 Most modules will provide transparent layers. Opaque layer is for modules
2139 which implement actual file system calls (like DB-based VFS). For example,
2140 default POSIX VFS which is built in into Samba is an opaque VFS module.
2142 Other layer types (logger, splitter, scanner) were designed to provide different
2143 degree of transparency and for diagnosing VFS module behaviour.
2145 Each module can implement several layers at the same time provided that only
2146 one layer is used per each operation.
2147 </p><pre class=
"programlisting">
2148 typedef enum _vfs_op_layer {
2149 SMB_VFS_LAYER_NOOP = -
1, /* - For using in VFS module to indicate end of array */
2150 /* of operations description */
2151 SMB_VFS_LAYER_OPAQUE =
0, /* - Final level, does not call anything beyond itself */
2152 SMB_VFS_LAYER_TRANSPARENT, /* - Normal operation, calls underlying layer after */
2153 /* possibly changing passed data */
2154 SMB_VFS_LAYER_LOGGER, /* - Logs data, calls underlying layer, logging may not */
2156 SMB_VFS_LAYER_SPLITTER, /* - Splits operation, calls underlying layer _and_ own facility, */
2157 /* then combines result */
2158 SMB_VFS_LAYER_SCANNER /* - Checks data and possibly initiates additional */
2159 /* file activity like logging to files _inside_ samba VFS */
2161 </pre></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2895409"></a>The Interaction between the Samba VFS subsystem and the modules
</h2></div></div><div></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2895418"></a>Initialization and registration
</h3></div></div><div></div></div><p>
2162 As each Samba module a VFS module should have a
2163 </p><pre class=
"programlisting">NTSTATUS vfs_example_init(void);
</pre><p> function if it's staticly linked to samba or
2164 </p><pre class=
"programlisting">NTSTATUS init_module(void);
</pre><p> function if it's a shared module.
2166 This should be the only non static function inside the module.
2167 Global variables should also be static!
2169 The module should register its functions via the
2170 </p><pre class=
"programlisting">
2171 NTSTATUS smb_register_vfs(int version, const char *name, vfs_op_tuple *vfs_op_tuples);
2173 </p><div class=
"variablelist"><dl><dt><span class=
"term">version
</span></dt><dd><p>should be filled with SMB_VFS_INTERFACE_VERSION
</p></dd><dt><span class=
"term">name
</span></dt><dd><p>this is the name witch can be listed in the
2174 <b class=
"command">vfs objects
</b> parameter to use this module.
</p></dd><dt><span class=
"term">vfs_op_tuples
</span></dt><dd><p>
2175 this is an array of vfs_op_tuple's.
2176 (vfs_op_tuples is descripted in details below.)
2177 </p></dd></dl></div><p>
2178 For each operation the module wants to provide it has a entry in the
2180 </p><pre class=
"programlisting">
2181 typedef struct _vfs_op_tuple {
2186 </pre><div class=
"variablelist"><dl><dt><span class=
"term">op
</span></dt><dd><p>the function pointer to the specified function.
</p></dd><dt><span class=
"term">type
</span></dt><dd><p>the vfs_op_type of the function to specified witch operation the function provides.
</p></dd><dt><span class=
"term">layer
</span></dt><dd><p>the vfs_op_layer in whitch the function operates.
</p></dd></dl></div><p>A simple example:
</p><pre class=
"programlisting">
2187 static vfs_op_tuple example_op_tuples[] = {
2188 {SMB_VFS_OP(example_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT},
2189 {SMB_VFS_OP(example_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_TRANSPARENT},
2191 {SMB_VFS_OP(example_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_OPAQUE},
2193 /* This indicates the end of the array */
2194 {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
2197 NTSTATUS init_module(void)
2199 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
"example
", example_op_tuples);
2201 </pre></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2895609"></a>How the Modules handle per connection data
</h3></div></div><div></div></div><p>Each VFS function has as first parameter a pointer to the modules vfs_handle_struct.
2202 </p><pre class=
"programlisting">
2203 typedef struct vfs_handle_struct {
2204 struct vfs_handle_struct *next, *prev;
2206 struct vfs_ops vfs_next;
2207 struct connection_struct *conn;
2209 void (*free_data)(void **data);
2210 } vfs_handle_struct;
2211 </pre><div class=
"variablelist"><dl><dt><span class=
"term">param
</span></dt><dd><p>this is the module parameter specified in the
<b class=
"command">vfs objects
</b> parameter.
</p><p>e.g. for 'vfs objects = example:test' param would be
"test
".
</p></dd><dt><span class=
"term">vfs_next
</span></dt><dd><p>This vfs_ops struct contains the information for calling the next module operations.
2212 Use the SMB_VFS_NEXT_* macros to call a next module operations and
2213 don't access handle-
>vfs_next.ops.* directly!
</p></dd><dt><span class=
"term">conn
</span></dt><dd><p>This is a pointer back to the connection_struct to witch the handle belongs.
</p></dd><dt><span class=
"term">data
</span></dt><dd><p>This is a pointer for holding module private data.
2214 You can alloc data with connection life time on the handle-
>conn-
>mem_ctx TALLOC_CTX.
2215 But you can also manage the memory allocation yourself.
</p></dd><dt><span class=
"term">free_data
</span></dt><dd><p>This is a function pointer to a function that free's the module private data.
2216 If you talloc your private data on the TALLOC_CTX handle-
>conn-
>mem_ctx,
2217 you can set this function pointer to NULL.
</p></dd></dl></div><p>Some useful MACROS for handle private data.
2218 </p><pre class=
"programlisting">
2219 #define SMB_VFS_HANDLE_GET_DATA(handle, datap, type, ret) { \
2220 if (!(handle)||((datap=(type *)(handle)-
>data)==NULL)) { \
2221 DEBUG(
0,(
"%s() failed to get vfs_handle-
>data!\n
",FUNCTION_MACRO)); \
2226 #define SMB_VFS_HANDLE_SET_DATA(handle, datap, free_fn, type, ret) { \
2228 DEBUG(
0,(
"%s() failed to set handle-
>data!\n
",FUNCTION_MACRO)); \
2231 if ((handle)-
>free_data) { \
2232 (handle)-
>free_data(
&(handle)-
>data); \
2234 (handle)-
>data = (void *)datap; \
2235 (handle)-
>free_data = free_fn; \
2239 #define SMB_VFS_HANDLE_FREE_DATA(handle) { \
2240 if ((handle)
&& (handle)-
>free_data) { \
2241 (handle)-
>free_data(
&(handle)-
>data); \
2244 </pre><p>How SMB_VFS_LAYER_TRANSPARENT functions can call the SMB_VFS_LAYER_OPAQUE functions.
</p><p>The easiest way to do this is to use the SMB_VFS_OPAQUE_* macros.
2245 </p><pre class=
"programlisting">
2247 /* File operations */
2248 #define SMB_VFS_OPAQUE_OPEN(conn, fname, flags, mode) \
2249 ((conn)-
>vfs_opaque.ops.open(\
2250 (conn)-
>vfs_opaque.handles.open,\
2251 (conn), (fname), (flags), (mode)))
2252 #define SMB_VFS_OPAQUE_CLOSE(fsp, fd) \
2253 ((fsp)-
>conn-
>vfs_opaque.ops.close(\
2254 (fsp)-
>conn-
>vfs_opaque.handles.close,\
2256 #define SMB_VFS_OPAQUE_READ(fsp, fd, data, n) \
2257 ((fsp)-
>conn-
>vfs_opaque.ops.read(\
2258 (fsp)-
>conn-
>vfs_opaque.handles.read,\
2259 (fsp), (fd), (data), (n)))
2260 #define SMB_VFS_OPAQUE_WRITE(fsp, fd, data, n) \
2261 ((fsp)-
>conn-
>vfs_opaque.ops.write(\
2262 (fsp)-
>conn-
>vfs_opaque.handles.write,\
2263 (fsp), (fd), (data), (n)))
2264 #define SMB_VFS_OPAQUE_LSEEK(fsp, fd, offset, whence) \
2265 ((fsp)-
>conn-
>vfs_opaque.ops.lseek(\
2266 (fsp)-
>conn-
>vfs_opaque.handles.lseek,\
2267 (fsp), (fd), (offset), (whence)))
2268 #define SMB_VFS_OPAQUE_SENDFILE(tofd, fsp, fromfd, header, offset, count) \
2269 ((fsp)-
>conn-
>vfs_opaque.ops.sendfile(\
2270 (fsp)-
>conn-
>vfs_opaque.handles.sendfile,\
2271 (tofd), (fsp), (fromfd), (header), (offset), (count)))
2273 </pre><p>How SMB_VFS_LAYER_TRANSPARENT functions can call the next modules functions.
</p><p>The easiest way to do this is to use the SMB_VFS_NEXT_* macros.
2274 </p><pre class=
"programlisting">
2276 /* File operations */
2277 #define SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode) \
2278 ((handle)-
>vfs_next.ops.open(\
2279 (handle)-
>vfs_next.handles.open,\
2280 (conn), (fname), (flags), (mode)))
2281 #define SMB_VFS_NEXT_CLOSE(handle, fsp, fd) \
2282 ((handle)-
>vfs_next.ops.close(\
2283 (handle)-
>vfs_next.handles.close,\
2285 #define SMB_VFS_NEXT_READ(handle, fsp, fd, data, n) \
2286 ((handle)-
>vfs_next.ops.read(\
2287 (handle)-
>vfs_next.handles.read,\
2288 (fsp), (fd), (data), (n)))
2289 #define SMB_VFS_NEXT_WRITE(handle, fsp, fd, data, n) \
2290 ((handle)-
>vfs_next.ops.write(\
2291 (handle)-
>vfs_next.handles.write,\
2292 (fsp), (fd), (data), (n)))
2293 #define SMB_VFS_NEXT_LSEEK(handle, fsp, fd, offset, whence) \
2294 ((handle)-
>vfs_next.ops.lseek(\
2295 (handle)-
>vfs_next.handles.lseek,\
2296 (fsp), (fd), (offset), (whence)))
2297 #define SMB_VFS_NEXT_SENDFILE(handle, tofd, fsp, fromfd, header, offset, count) \
2298 ((handle)-
>vfs_next.ops.sendfile(\
2299 (handle)-
>vfs_next.handles.sendfile,\
2300 (tofd), (fsp), (fromfd), (header), (offset), (count)))
2302 </pre></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2895852"></a>Upgrading to the New VFS Interface
</h2></div></div><div></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2895860"></a>Upgrading from
2.2.* and
3.0aplha modules
</h3></div></div><div></div></div><div class=
"orderedlist"><ol type=
"1"><li><p>
2303 Add
"vfs_handle_struct *handle,
" as first parameter to all vfs operation functions.
2304 e.g. example_connect(connection_struct *conn, const char *service, const char *user);
2305 -
> example_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user);
2307 Replace
"default_vfs_ops.
" with
"smb_vfs_next_
".
2308 e.g. default_vfs_ops.connect(conn, service, user);
2309 -
> smb_vfs_next_connect(conn, service, user);
2311 Uppercase all
"smb_vfs_next_*
" functions.
2312 e.g. smb_vfs_next_connect(conn, service, user);
2313 -
> SMB_VFS_NEXT_CONNECT(conn, service, user);
2315 Add
"handle,
" as first parameter to all SMB_VFS_NEXT_*() calls.
2316 e.g. SMB_VFS_NEXT_CONNECT(conn, service, user);
2317 -
> SMB_VFS_NEXT_CONNECT(handle, conn, service, user);
2319 (Only for
2.2.* modules)
2320 Convert the old struct vfs_ops example_ops to
2321 a vfs_op_tuple example_op_tuples[] array.
2323 </p><pre class=
"programlisting">
2324 struct vfs_ops example_ops = {
2325 /* Disk operations */
2326 example_connect, /* connect */
2327 example_disconnect, /* disconnect */
2328 NULL, /* disk free *
2329 /* Directory operations */
2334 NULL, /* closedir */
2335 /* File operations */
2341 NULL, /* sendfile */
2344 example_stat, /* stat */
2345 example_fstat, /* fstat */
2346 example_lstat, /* lstat */
2355 NULL, /* ftruncate */
2358 NULL, /* readlink */
2361 NULL, /* realpath */
2362 NULL, /* fget_nt_acl */
2363 NULL, /* get_nt_acl */
2364 NULL, /* fset_nt_acl */
2365 NULL, /* set_nt_acl */
2367 NULL, /* chmod_acl */
2368 NULL, /* fchmod_acl */
2370 NULL, /* sys_acl_get_entry */
2371 NULL, /* sys_acl_get_tag_type */
2372 NULL, /* sys_acl_get_permset */
2373 NULL, /* sys_acl_get_qualifier */
2374 NULL, /* sys_acl_get_file */
2375 NULL, /* sys_acl_get_fd */
2376 NULL, /* sys_acl_clear_perms */
2377 NULL, /* sys_acl_add_perm */
2378 NULL, /* sys_acl_to_text */
2379 NULL, /* sys_acl_init */
2380 NULL, /* sys_acl_create_entry */
2381 NULL, /* sys_acl_set_tag_type */
2382 NULL, /* sys_acl_set_qualifier */
2383 NULL, /* sys_acl_set_permset */
2384 NULL, /* sys_acl_valid */
2385 NULL, /* sys_acl_set_file */
2386 NULL, /* sys_acl_set_fd */
2387 NULL, /* sys_acl_delete_def_file */
2388 NULL, /* sys_acl_get_perm */
2389 NULL, /* sys_acl_free_text */
2390 NULL, /* sys_acl_free_acl */
2391 NULL /* sys_acl_free_qualifier */
2395 </p><pre class=
"programlisting">
2396 static vfs_op_tuple example_op_tuples[] = {
2397 {SMB_VFS_OP(example_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT},
2398 {SMB_VFS_OP(example_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_TRANSPARENT},
2400 {SMB_VFS_OP(example_fstat), SMB_VFS_OP_FSTAT, SMB_VFS_LAYER_TRANSPARENT},
2401 {SMB_VFS_OP(example_stat), SMB_VFS_OP_STAT, SMB_VFS_LAYER_TRANSPARENT},
2402 {SMB_VFS_OP(example_lstat), SMB_VFS_OP_LSTAT, SMB_VFS_LAYER_TRANSPARENT},
2404 {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
2408 Move the example_op_tuples[] array to the end of the file.
2410 Add the init_module() function at the end of the file.
2412 </p><pre class=
"programlisting">
2413 NTSTATUS init_module(void)
2415 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
"example
",example_op_tuples);
2419 Check if your vfs_init() function does more then just prepare the vfs_ops structs or
2420 remember the struct smb_vfs_handle_struct.
2421 </p><table class=
"simplelist" border=
"0" summary=
"Simple list"><tr><td>If NOT you can remove the vfs_init() function.
</td></tr><tr><td>If YES decide if you want to move the code to the example_connect() operation or to the init_module(). And then remove vfs_init().
2422 e.g. a debug class registration should go into init_module() and the allocation of private data should go to example_connect().
</td></tr></table><p>
2424 (Only for
3.0alpha* modules)
2425 Check if your vfs_done() function contains needed code.
2426 </p><table class=
"simplelist" border=
"0" summary=
"Simple list"><tr><td>If NOT you can remove the vfs_done() function.
</td></tr><tr><td>If YES decide if you can move the code to the example_disconnect() operation. Otherwise register a SMB_EXIT_EVENT with smb_register_exit_event(); (Described in the
<a href=
"#modules" title=
"Chapter 15. Modules">modules section
</a>) And then remove vfs_done(). e.g. the freeing of private data should go to example_disconnect().
2427 </td></tr></table><p>
2429 Check if you have any global variables left.
2430 Decide if it wouldn't be better to have this data on a connection basis.
2431 </p><table class=
"simplelist" border=
"0" summary=
"Simple list"><tr><td>If NOT leave them as they are. (e.g. this could be the variable for the private debug class.)
</td></tr><tr><td>If YES pack all this data into a struct. You can use handle-
>data to point to such a struct on a per connection basis.
</td></tr></table><p>
2433 e.g. if you have such a struct:
2434 </p><pre class=
"programlisting">
2435 struct example_privates {
2440 first way of doing it:
2441 </p><pre class=
"programlisting">
2442 static int example_connect(vfs_handle_struct *handle,
2443 connection_struct *conn, const char *service,
2446 struct example_privates *data = NULL;
2448 /* alloc our private data */
2449 data = (struct example_privates *)talloc_zero(conn-
>mem_ctx, sizeof(struct example_privates));
2451 DEBUG(
0,(
"talloc_zero() failed\n
"));
2455 /* init out private data */
2456 data-
>some_string = talloc_strdup(conn-
>mem_ctx,
"test
");
2457 if (!data-
>some_string) {
2458 DEBUG(
0,(
"talloc_strdup() failed\n
"));
2462 data-
>db_connection = open_db_conn();
2464 /* and now store the private data pointer in handle-
>data
2465 * we don't need to specify a free_function here because
2466 * we use the connection TALLOC context.
2467 * (return -
1 if something failed.)
2469 VFS_HANDLE_SET_DATA(handle, data, NULL, struct example_privates, return -
1);
2471 return SMB_VFS_NEXT_CONNECT(handle,conn,service,user);
2474 static int example_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
2476 struct example_privates *data = NULL;
2478 /* get the pointer to our private data
2479 * return -
1 if something failed
2481 SMB_VFS_HANDLE_GET_DATA(handle, data, struct example_privates, return -
1);
2483 /* do something here...*/
2484 DEBUG(
0,(
"some_string: %s\n
",data-
>some_string));
2486 return SMB_VFS_NEXT_CLOSE(handle, fsp, fd);
2489 second way of doing it:
2490 </p><pre class=
"programlisting">
2491 static void free_example_privates(void **datap)
2493 struct example_privates *data = (struct example_privates *)*datap;
2495 SAFE_FREE(data-
>some_string);
2503 static int example_connect(vfs_handle_struct *handle,
2504 connection_struct *conn, const char *service,
2507 struct example_privates *data = NULL;
2509 /* alloc our private data */
2510 data = (struct example_privates *)malloc(sizeof(struct example_privates));
2512 DEBUG(
0,(
"malloc() failed\n
"));
2516 /* init out private data */
2517 data-
>some_string = strdup(conn-
>mem_ctx,
"test
");
2518 if (!data-
>some_string) {
2519 DEBUG(
0,(
"strdup() failed\n
"));
2523 data-
>db_connection = open_db_conn();
2525 /* and now store the private data pointer in handle-
>data
2526 * we need to specify a free_function because we used malloc() and strdup().
2527 * (return -
1 if something failed.)
2529 SMB_VFS_HANDLE_SET_DATA(handle, data, NULL, struct example_privates, return -
1);
2531 return SMB_VFS_NEXT_CONNECT(handle,conn,service,user);
2534 static int example_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
2536 struct example_privates *data = NULL;
2538 /* get the pointer to our private data
2539 * return -
1 if something failed
2541 SMB_VFS_HANDLE_GET_DATA(handle, data, struct example_privates, return -
1);
2543 /* do something here...*/
2544 DEBUG(
0,(
"some_string: %s\n
",data-
>some_string));
2546 return SMB_VFS_NEXT_CLOSE(handle, fsp, fd);
2550 To make it easy to build
3rd party modules it would be usefull to provide
2551 configure.in, (configure), install.sh and Makefile.in with the module.
2552 (Take a look at the example in
<tt class=
"filename">examples/VFS
</tt>.)
2554 The configure script accepts
<tt class=
"option">--with-samba-source
</tt> to specify
2555 the path to the samba source tree.
2556 It also accept
<tt class=
"option">--enable-developer
</tt> which lets the compiler
2557 give you more warnings.
2559 The idea is that you can extend this
2560 <tt class=
"filename">configure.in
</tt> and
<tt class=
"filename">Makefile.in
</tt> scripts
2563 Compiling
& Testing...
2564 </p><table class=
"simplelist" border=
"0" summary=
"Simple list"><tr><td><b class=
"userinput"><tt>./configure
<tt class=
"option">--enable-developer
</tt></tt></b> ...
</td></tr><tr><td><b class=
"userinput"><tt>make
</tt></b></td></tr><tr><td>Try to fix all compiler warnings
</td></tr><tr><td><b class=
"userinput"><tt>make
</tt></b></td></tr><tr><td>Testing, Testing, Testing ...
</td></tr></table><p>
2565 </p></li></ol></div></div></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2896401"></a>Some Notes
</h2></div></div><div></div></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2896408"></a>Implement TRANSPARENT functions
</h3></div></div><div></div></div><p>
2566 Avoid writing functions like this:
2568 </p><pre class=
"programlisting">
2569 static int example_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
2571 return SMB_VFS_NEXT_CLOSE(handle, fsp, fd);
2575 Overload only the functions you really need to!
2576 </p></div><div class=
"sect2" lang=
"en"><div class=
"titlepage"><div><div><h3 class=
"title"><a name=
"id2896432"></a>Implement OPAQUE functions
</h3></div></div><div></div></div><p>
2577 If you want to just implement a better version of a
2578 default samba opaque function
2579 (e.g. like a disk_free() function for a special filesystem)
2580 it's ok to just overload that specific function.
2582 If you want to implement a database filesystem or
2583 something different from a posix filesystem.
2584 Make sure that you overload every vfs operation!!!
2586 Functions your FS does not support should be overloaded by something like this:
2587 e.g. for a readonly filesystem.
2588 </p><pre class=
"programlisting">
2589 static int example_rename(vfs_handle_struct *handle, connection_struct *conn,
2590 char *oldname, char *newname)
2592 DEBUG(
10,(
"function rename() not allowed on vfs 'example'\n
"));
2596 </pre></div></div></div><div class=
"chapter" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title"><a name=
"Packaging"></a>Chapter
18. Notes to packagers
</h2></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Jelmer
</span> <span class=
"surname">Vernooij
</span></h3></div></div></div><div></div></div><div class=
"toc"><p><b>Table of Contents
</b></p><dl><dt><a href=
"#id2895009">Versioning
</a></dt><dt><a href=
"#id2895042">Modules
</a></dt></dl></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2895009"></a>Versioning
</h2></div></div><div></div></div><p>Please, please update the version number in
2597 <tt class=
"filename">source/include/version.h
</tt> to include the versioning of your package. This makes it easier to distinguish standard samba builds
2598 from custom-build samba builds (distributions often patch packages). For
2599 example, a good version would be:
</p><pre class=
"programlisting">
2600 Version
2.999+
3.0.alpha21-
5 for Debian
2601 </pre></div><div class=
"sect1" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both"><a name=
"id2895042"></a>Modules
</h2></div></div><div></div></div><p>Samba now has support for building parts of samba as plugins. This
2602 makes it possible to, for example, put ldap or mysql support in a seperate
2603 package, thus making it possible to have a normal samba package not
2604 depending on ldap or mysql. To build as much parts of samba
2605 as a plugin, run:
</p><pre class=
"programlisting">
2606 ./configure --with-shared-modules=rpc,vfs,auth,pdb,charset
2607 </pre></div></div><div class=
"chapter" lang=
"en"><div class=
"titlepage"><div><div><h2 class=
"title"><a name=
"contributing"></a>Chapter
19. Contributing code
</h2></div><div><div class=
"author"><h3 class=
"author"><span class=
"firstname">Jelmer
</span> <span class=
"othername">R.
</span> <span class=
"surname">Vernooij
</span></h3><div class=
"affiliation"><span class=
"orgname">The Samba Team
<br></span><div class=
"address"><p><tt class=
"email"><<a href=
"mailto:jelmer@samba.org">jelmer@samba.org
</a>></tt></p></div></div></div></div></div><div></div></div><p>Here are a few tips and notes that might be useful if you are
2608 interested in modifying samba source code and getting it into
2609 samba's main branch.
</p><div class=
"variablelist"><dl><dt><span class=
"term">Retrieving the source
</span></dt><dd><p>In order to contribute code to samba, make sure you have the
2610 latest source. Retrieving the samba source code from CVS is
2611 documented in the appendix of the Samba HOWTO Collection.
2612 </p></dd><dt><span class=
"term">Discuss large modifications with team members
</span></dt><dd><p>Please discuss large modifications you are going to make
2613 with members of the samba team. Some parts of the samba code
2614 have one or more 'owners' - samba developers who wrote most
2615 of the code and maintain it.
2616 </p><p>This way you can avoid spending your time and effort on
2617 something that is not going to make it into the main samba branch
2618 because someone else was working on the same thing or because your
2619 implementation is not the correct one.
2620 </p></dd><dt><span class=
"term">Patch format
</span></dt><dd><p>Patches to the samba tree should be in unified diff format,
2621 e.g. files generated by
<b class=
"userinput"><tt>diff -u
</tt></b>.
2622 </p><p>If you are modifying a copy of samba you retrieved from CVS,
2623 you can easily generate a diff file of these changes by running
2624 <b class=
"userinput"><tt>cvs diff -u
</tt></b>.
</p></dd><dt><span class=
"term">Points of attention when modifying samba source code
</span></dt><dd><p>
2625 </p><table class=
"simplelist" border=
"0" summary=
"Simple list"><tr><td>Don't simply copy code from other places and modify it until it
2626 works. Code needs to be clean and logical. Duplicate
2627 code is to be avoided.
</td></tr><tr><td>Test your patch. It might take a while before one of us looks
2628 at your patch so it will take longer before your patch when your patch
2629 needs to go thru the review cycle again.
</td></tr><tr><td>Don't put seperate patches in one large diff file. This makes
2630 it harder to read, understand and test the patch. You might
2631 also risk not getting a good patch committed because you mixed it
2632 with one that had issues.
</td></tr><tr><td>Make sure your patch complies to the samba coding style as
2633 suggested in the coding-suggestions chapter.
</td></tr></table><p>
2634 </p></dd><dt><span class=
"term">Sending in bugfixes
</span></dt><dd><p>Bugfixes to bugs in samba should be submitted to samba's
2635 <a href=
"https://bugzilla.samba.org/" target=
"_top">bugzilla system
</a>,
2636 along with a description of the bug.
2637 </p></dd><dt><span class=
"term">Sending in feature patches
</span></dt><dd><p>Send feature patches along with a description of what the
2638 patch is supposed to do to the
2639 <a href=
"mailto:samba-technical@samba.org" target=
"_top">Samba-technical mailinglist
</a> and possibly to a samba team member who is (one of the) 'owners'
2640 of the code you made modifications to. We are all busy people
2641 so everybody tends to 'let one of the others handle it'. If nobody
2642 responded to your patch for a week, try to send it again until you
2643 get a response from one of us.
2644 </p></dd><dt><span class=
"term">Feedback on your patch
</span></dt><dd><p>One of the team members will look at your patch and either
2645 commit your patch or give comments why he won't apply it. In the
2646 latter case you can fix your patch and re-send it until
2647 your patch is approved.
</p></dd></dl></div></div></div></body></html>