Use entities and add overview of directories
[sfrench/samba-autobuild/.git] / docs / docbook / devdoc / sam.sgml
1 <chapter id="sam">
2
3 <chapterinfo>
4         <author>
5                 <firstname>Andrew</firstname><surname>Bartlett</surname>
6         </author>
7         <pubdate>1 October 2002</pubdate>
8 </chapterinfo>
9
10 <title>The Upcoming SAM System</title>
11
12 <note><para>The design as described in this document is _NOT_ the design that 
13 made it into samba 3.0. </para></note>
14
15 <sect1>
16 <title>Security in the 'new SAM'</title>
17
18 <para>One of the biggest problems with passdb is it's implementation of
19 'security'.  Access control is on a 'are you root at the moment' basis,
20 and it has no concept of NT ACLs.  Things like ldapsam had to add
21 'magic' 'are you root' checks.</para>
22
23 <para>We took this very seriously when we started work, and the new structure
24 is designed with this in mind, from the ground up.  Each call to the SAM
25 has a NT_TOKEN and (if relevant) an 'access desired'.  This is either
26 provided as a parameter, or implicitly supplied by the object being
27 accessed.</para>
28
29 <para>
30 For example, when you call 
31 </para>
32
33 <programlisting>
34 NTSTATUS sam_get_account_by_name(const SAM_CONTEXT *context, const
35 NT_USER_TOKEN *access_token, uint32 access_desired, const char *domain,
36 const char *name, SAM_ACCOUNT_HANDLE **account)
37 </programlisting>
38
39 <para>
40 The context can be NULL (and is used to allow import/export by setting
41 up 2 contexts, and allowing calls on both simultaneously)
42 </para>
43
44 <para>
45 The access token *must* be specified.  Normally the user's token out of
46 current_user, this can also be a global 'system' context.
47 </para>
48
49 <para>
50 The access desired is as per the ACL, for passing to the seaccess stuff.
51 </para>
52
53 <para>
54 The domain/username are standard.  Even if we only have one domain,
55 keeping this ensures that we don't get 'unqualified' usernames (same
56 problem as we had with unqualified SIDs).
57 </para>
58
59 <para>
60 We return a 'handle'.  This is opaque to the rest of Samba, but is
61 operated on by get/set routines, all of which return NTSTATUS.
62 </para>
63
64 <para>
65 The access checking is done by the SAM module.   The reason it is not
66 done 'above' the interface is to ensure a 'choke point'.  I put a lot of
67 effort into the auth subsystem to ensure we never 'accidentally' forgot
68 to check for null passwords, missed a restriction etc.  I intend the SAM
69 to be written with the same caution.
70 </para>
71
72 <para>
73 The reason the access checking is not handled by the interface itself is
74 due to the different implementations it make take on.  For example, on
75 ADS, you cannot set a password over a non-SSL connection.  Other
76 backends may have similar requirements - we need to leave this policy up
77 to the modules.  They will naturally have access to 'helper' procedures
78 and good examples to avoid mishaps.
79 </para>
80
81 <para>
82 (Furthermore, some backends my actually chose to push the whole ACL
83 issue to the remote server, and - assuming ldap for this example - bind
84 as the user directly)
85 </para>
86
87 <para>
88 Each returned handle has an internal 'access permitted', which allows
89 the 'get' and 'set' routines to return 'ACCESS_DENIED' for things that
90 were not able to be retrieved from the backend.  This removes the need
91 to specify the NT_TOKEN on every operation, and allows for 'object not
92 present' to be easily distinguished from 'access denied'.
93 </para>
94
95 <para>
96 When you 'set' an object (calling sam_update_account) the internal
97 details are again used.  Each change that has been made to the object
98 has been flagged, so as to avoid race conditions (on unmodified
99 components) and to avoid violating any extra ACL requirements on the
100 actual data store (like the LDAP server).
101 </para>
102
103 <para>
104 Finally, we have generic get_sec_desc() and set_sec_desc() routines to
105 allow external ACL manipulation.  These do lookups based on SID.
106 </para>
107
108 </sect1>
109
110 <sect1>
111 <title>Standalone from UNIX</title>
112
113 <para>
114 One of the primary tenants of the 'new SAM' is that it would not attempt
115 to deal with 'what unix id for that'.  This would be left to the 'SMS'
116 (Sid Mapping System') or SID farm, and probably administered via
117 winbind.  We have had constructive discussion on how 'basic' unix
118 accounts like 'root' would be handled, and we think this can work.  
119 Accounts not preexisting in unix would be served up via winbind.
120 </para>
121
122 <para>
123 This is an *optional* part, and my preferred end-game.  We have a fare
124 way to go before things like winbind up to it however.
125 </para>
126
127 </sect1>
128
129 <sect1>
130 <title>Handles and Races in the new SAM</title>
131
132 <para>
133 One of the things that the 'new SAM' work has tried to face is both
134 compatibility with existing code, and a closer alignment to the SAMR
135 interface.  I consider SAMR to be a 'primary customer' to the this work,
136 because if we get alignment with that wrong, things get more, rather
137 than less complex.  Also, most other parts of Samba are much more
138 flexible with what they can allow.
139 </para>
140
141 <para>
142 In any case, that was a decision taken as to how the general design
143 would progress.  BTW, my understanding of SAMR may be completely flawed.
144 </para>
145
146 <para>
147 One of the most race-prone areas of the new code is the conflicting
148 update problem.  We have taken two approaches:  
149 </para>
150
151 <itemizedlist>
152 <listitem>
153 <para>'Not conflicting' conflicts.  Due to the way usrmgr operates, it will
154 open a user, display all the properties and *save* them all, even if you
155 don't change any.
156 </para>
157
158 <para>
159 For this, see what I've done in rpc_server/srv_samr_util.c.  I intend
160 to take this one step further, and operate on the 'handle' that the
161 values were read from.  This should mean that we only update things that
162 have *really* changed.
163 </para>
164 </listitem>
165
166 <listitem>
167 <para>
168 'conflicting' updates:  Currently we don't deal with this (in passdb
169 or the new sam stuff), but the design is sufficiently flexible to 'deny'
170 a second update.  I don't foresee locking records however.
171 </para>
172 </listitem>
173 </itemizedlist>
174
175 </sect1>
176
177 <sect1>
178 <title>Layers</title>
179
180 <sect2>
181 <title>Application</title>
182
183 <para>
184 This is where smbd, samtest and whatever end-user replacement we have
185 for pdbedit sits.  They use only the SAM interface, and do not get
186 'special knowledge' of what is below them.
187 </para>
188 </sect2>
189 <sect2>
190 <title>SAM Interface</title>
191
192 <para>
193 This level 'owns' the various handle structures, the get/set routines on
194 those structures and provides the public interface.  The application
195 layer may initialize a 'context' to be passed to all interface routines,
196 else a default, self-initialising context will be supplied.  This layser
197 finds the appropriate backend module for the task, and tries very hard
198 not to need to much 'knowledge'.  It should just provide the required
199 abstraction to the modules below, and arrange for their initial loading.
200 </para>
201
202 <para>
203 We could possibly add ACL checking at this layer, to avoid discrepancies
204 in implementation modules.
205 </para>
206
207 </sect2>
208
209 <sect2>
210 <title>SAM Modules</title>
211
212 <para>
213 These do not communicate with the application directly, only by setting
214 values in the handles, and receiving requests from the interface.  These
215 modules are responsible for translating values from the handle's
216 .private into (say) an LDAP modification list.  The module is expected
217 to 'know' things like it's own domain SID, domain name, and any other
218 state attached to the SAM.  Simpler modules may call back to some helper
219 routine.
220 </para>
221
222 </sect2>
223 </sect1>
224
225 <sect1>
226 <title>SAM Modules</title>
227
228 <sect2>
229 <title>Special Module: sam_passdb</title>
230
231 <para>
232 In order for there to be a smooth transition, kai is writing a module
233 that reads existing passdb backends, and translates them into SAM
234 replies.  (Also pulling data from the account policy DB etc).  We also
235 intend to write a module that does the reverse - gives the SAM a passdb
236 interface.
237 </para>
238 </sect2>
239
240 <sect2>
241 <title>sam_ads</title>
242 <para>
243 This is the first of the SAM modules to be committed to the tree -
244 mainly because I needed to coordinate work with metze (who authored most
245 of it).  This module aims to use Samba's libads code to provide an
246 Active Directory LDAP client, suitable for use on a mixed-mode DC. 
247 While it is currently being tested against Win2k servers (with a
248 password in the smb.conf file) it is expected to eventually use a
249 (possibly modified) OpenLDAP server.  We hope that this will assist in
250 the construction of an Samba AD DC.
251 </para>
252
253 <para>
254 We also intend to construct a Samba 2.2/3.0 compatible ldap module,
255 again using libads code.
256 </para>
257 </sect2>
258 </sect1>
259
260 <sect1>
261 <title>Memory Management</title>
262
263 <para> 
264 The 'new SAM' development effort also concerned itself with getting a
265 sane implementation of memory management.  It was decided that we would
266 be (as much as possible) talloc based, using an 'internal talloc
267 context' on many objects.  That is, the creation of an object would
268 initiate it's own internal talloc context, and this would be used for
269 all operations on that object.  Much of this is already implemented in
270 passdb.  Also, like passdb, it will be possible to specify that some
271 object actually be created on a specified context.  
272 </para>
273
274 <para>
275 Memory management is important here because the APIs in the 'new SAM' do
276 not use 'pdb_init()' or an equivalent.  They always allocate new
277 objects.  Enumeration's are slightly different, and occur on a supplied
278 context that 'owns' the entire list, rather than per-element.  (the
279 enumeration functions return an array of all elements - not full handles
280 just basic (and public) info)  Likewise for things that fill in a char
281 **.
282 </para>
283
284 <para>For example:</para>
285
286 <para><programlisting>
287 NTSTATUS sam_lookup_sid(const SAM_CONTEXT *context, const NT_USER_TOKEN
288 *access_token, TALLOC_CTX *mem_ctx, const DOM_SID *sid, char **name,
289 uint32 *type)
290 </programlisting></para>
291
292 <para>Takes a context to allocate the 'name' on, while:</para>
293
294 <para><programlisting>
295 NTSTATUS sam_get_account_by_sid(const SAM_CONTEXT *context, const
296 NT_USER_TOKEN *access_token, uint32 access_desired, const DOM_SID
297 *accountsid, SAM_ACCOUNT_HANDLE **account)
298 </programlisting></para>
299
300 <para>Allocates a handle and stores the allocation context on that handle.</para>
301
302 <para>I think that the following:</para>
303
304 <para><programlisting>
305 NTSTATUS sam_enum_accounts(const SAM_CONTEXT *context, const
306 NT_USER_TOKEN *access_token, const DOM_SID *domainsid, uint16 acct_ctrl,
307 int32 *account_count, SAM_ACCOUNT_ENUM **accounts)
308 </programlisting></para>
309
310 </sect1>
311
312 <sect1>
313 <title>Testing</title>
314
315 <para>
316 Testing is vital in any piece of software, and Samba is certainly no
317 exception. In designing this new subsystem, we have taken care to ensure
318 it is easily tested, independent of outside protocols.
319 </para>
320
321 <para>
322 To this end, Jelmer has constructed 'samtest'.  
323 </para>
324
325 <para>
326 This utility (see torture/samtest.c) is structured like rpcclient, but
327 instead operates on the SAM subsystem.  It creates a 'custom' SAM
328 context, that may be distinct from the default values used by the rest
329 of the system, and can load a separate configuration file.  
330 </para>
331
332 <para>
333 A small number of commands are currently implemented, but these have
334 already proved vital in testing.   I expect SAM module authors will find
335 it particularly valuable.
336 </para>
337
338 <para>Example useage:</para>
339
340 <para><prompt>$</prompt> <command>bin/samtest</command></para>
341
342 <para><programlisting>
343 > context ads:ldap://192.168.1.96
344 </programlisting>
345 (this loads a new context, using the new ADS module.  The parameter is
346 the 'location' of the ldap server)
347 </para>
348
349 <para><programlisting>
350 > lookup_name DOMAIN abartlet
351 </programlisting>
352 (returns a sid).
353 </para>
354
355 <para>
356 Because the 'new SAM' is NT ACL based, there will be a command to
357 specify an arbitrary NT ACL, but for now it uses 'system' by default.
358 </para>
359 </sect1>
360 </chapter>