2 Unix SMB/CIFS implementation.
3 Authentication utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Andrew Bartlett 2001-2010
6 Copyright (C) Jeremy Allison 2000-2001
7 Copyright (C) Rafal Szczesniak 2002
8 Copyright (C) Stefan Metzmacher 2005
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "libcli/security/security.h"
26 #include "auth/credentials/credentials.h"
27 #include "param/param.h"
28 #include "auth/auth.h" /* for auth_user_info_dc */
29 #include "auth/session.h"
30 #include "auth/system_session_proto.h"
33 #define DBGC_CLASS DBGC_AUTH
36 prevent the static system session being freed
38 static int system_session_destructor(struct auth_session_info
*info
)
43 /* Create a security token for a session SYSTEM (the most
44 * trusted/privileged account), including the local machine account as
45 * the off-host credentials
47 _PUBLIC_
struct auth_session_info
*system_session(struct loadparm_context
*lp_ctx
)
49 static struct auth_session_info
*static_session
;
53 return static_session
;
57 * Use NULL here, not the autofree context for this
58 * static pointer. The destructor prevents freeing this
61 nt_status
= auth_system_session_info(NULL
,
64 if (!NT_STATUS_IS_OK(nt_status
)) {
65 TALLOC_FREE(static_session
);
68 talloc_set_destructor(static_session
, system_session_destructor
);
69 return static_session
;
72 NTSTATUS
auth_system_session_info(TALLOC_CTX
*parent_ctx
,
73 struct loadparm_context
*lp_ctx
,
74 struct auth_session_info
**_session_info
)
77 struct auth_user_info_dc
*user_info_dc
= NULL
;
78 struct auth_session_info
*session_info
= NULL
;
79 TALLOC_CTX
*mem_ctx
= NULL
;
82 mem_ctx
= talloc_new(parent_ctx
);
83 if (mem_ctx
== NULL
) {
84 return NT_STATUS_NO_MEMORY
;
87 nt_status
= auth_system_user_info_dc(mem_ctx
, lpcfg_netbios_name(lp_ctx
),
89 if (!NT_STATUS_IS_OK(nt_status
)) {
94 /* references the user_info_dc into the session_info */
95 nt_status
= auth_generate_session_info(parent_ctx
,
99 AUTH_SESSION_INFO_SIMPLE_PRIVILEGES
,
101 talloc_free(mem_ctx
);
103 NT_STATUS_NOT_OK_RETURN(nt_status
);
105 session_info
->credentials
= cli_credentials_init(session_info
);
106 if (!session_info
->credentials
) {
107 talloc_free(session_info
);
108 return NT_STATUS_NO_MEMORY
;
111 ok
= cli_credentials_set_conf(session_info
->credentials
, lp_ctx
);
113 talloc_free(session_info
);
114 return NT_STATUS_INTERNAL_ERROR
;
117 cli_credentials_set_machine_account_pending(session_info
->credentials
, lp_ctx
);
118 *_session_info
= session_info
;
123 NTSTATUS
auth_system_user_info_dc(TALLOC_CTX
*mem_ctx
, const char *netbios_name
,
124 struct auth_user_info_dc
**_user_info_dc
)
126 struct auth_user_info_dc
*user_info_dc
;
127 struct auth_user_info
*info
;
129 user_info_dc
= talloc_zero(mem_ctx
, struct auth_user_info_dc
);
130 NT_STATUS_HAVE_NO_MEMORY(user_info_dc
);
132 /* This returns a pointer to a struct dom_sid, which is the
133 * same as a 1 element list of struct dom_sid */
134 user_info_dc
->num_sids
= 1;
135 user_info_dc
->sids
= talloc(user_info_dc
, struct auth_SidAttr
);
136 if (user_info_dc
->sids
== NULL
) {
137 talloc_free(user_info_dc
);
138 return NT_STATUS_NO_MEMORY
;
141 user_info_dc
->sids
->sid
= global_sid_System
;
142 user_info_dc
->sids
->attrs
= SE_GROUP_DEFAULT_FLAGS
;
144 /* annoying, but the Anonymous really does have a session key,
145 and it is all zeros! */
146 user_info_dc
->user_session_key
= data_blob_talloc(user_info_dc
, NULL
, 16);
147 if (user_info_dc
->user_session_key
.data
== NULL
) {
148 talloc_free(user_info_dc
);
149 return NT_STATUS_NO_MEMORY
;
152 user_info_dc
->lm_session_key
= data_blob_talloc(user_info_dc
, NULL
, 16);
153 if (user_info_dc
->lm_session_key
.data
== NULL
) {
154 talloc_free(user_info_dc
);
155 return NT_STATUS_NO_MEMORY
;
158 data_blob_clear(&user_info_dc
->user_session_key
);
159 data_blob_clear(&user_info_dc
->lm_session_key
);
161 user_info_dc
->info
= info
= talloc_zero(user_info_dc
, struct auth_user_info
);
162 if (user_info_dc
->info
== NULL
) {
163 talloc_free(user_info_dc
);
164 return NT_STATUS_NO_MEMORY
;
167 info
->account_name
= talloc_strdup(info
, "SYSTEM");
168 if (info
->account_name
== NULL
) {
169 talloc_free(user_info_dc
);
170 return NT_STATUS_NO_MEMORY
;
173 info
->domain_name
= talloc_strdup(info
, "NT AUTHORITY");
174 if (info
->domain_name
== NULL
) {
175 talloc_free(user_info_dc
);
176 return NT_STATUS_NO_MEMORY
;
179 info
->full_name
= talloc_strdup(info
, "System");
180 if (info
->full_name
== NULL
) {
181 talloc_free(user_info_dc
);
182 return NT_STATUS_NO_MEMORY
;
185 info
->logon_script
= talloc_strdup(info
, "");
186 if (info
->logon_script
== NULL
) {
187 talloc_free(user_info_dc
);
188 return NT_STATUS_NO_MEMORY
;
191 info
->profile_path
= talloc_strdup(info
, "");
192 if (info
->profile_path
== NULL
) {
193 talloc_free(user_info_dc
);
194 return NT_STATUS_NO_MEMORY
;
197 info
->home_directory
= talloc_strdup(info
, "");
198 if (info
->home_directory
== NULL
) {
199 talloc_free(user_info_dc
);
200 return NT_STATUS_NO_MEMORY
;
203 info
->home_drive
= talloc_strdup(info
, "");
204 if (info
->home_drive
== NULL
) {
205 talloc_free(user_info_dc
);
206 return NT_STATUS_NO_MEMORY
;
209 info
->logon_server
= talloc_strdup(info
, netbios_name
);
210 if (info
->logon_server
== NULL
) {
211 talloc_free(user_info_dc
);
212 return NT_STATUS_NO_MEMORY
;
215 info
->last_logon
= 0;
216 info
->last_logoff
= 0;
217 info
->acct_expiry
= 0;
218 info
->last_password_change
= 0;
219 info
->allow_password_change
= 0;
220 info
->force_password_change
= 0;
222 info
->logon_count
= 0;
223 info
->bad_password_count
= 0;
225 info
->acct_flags
= ACB_NORMAL
;
227 info
->user_flags
= 0;
229 *_user_info_dc
= user_info_dc
;
235 static NTSTATUS
auth_domain_admin_user_info_dc(TALLOC_CTX
*mem_ctx
,
236 const char *netbios_name
,
237 const char *domain_name
,
238 struct dom_sid
*domain_sid
,
239 struct auth_user_info_dc
**_user_info_dc
)
241 struct auth_user_info_dc
*user_info_dc
;
242 struct auth_user_info
*info
;
244 user_info_dc
= talloc_zero(mem_ctx
, struct auth_user_info_dc
);
245 NT_STATUS_HAVE_NO_MEMORY(user_info_dc
);
247 user_info_dc
->num_sids
= 8;
248 user_info_dc
->sids
= talloc_array(user_info_dc
, struct auth_SidAttr
, user_info_dc
->num_sids
);
250 user_info_dc
->sids
[PRIMARY_USER_SID_INDEX
].sid
= *domain_sid
;
251 sid_append_rid(&user_info_dc
->sids
[PRIMARY_USER_SID_INDEX
].sid
, DOMAIN_RID_ADMINISTRATOR
);
252 user_info_dc
->sids
[PRIMARY_USER_SID_INDEX
].attrs
= SE_GROUP_DEFAULT_FLAGS
;
254 user_info_dc
->sids
[PRIMARY_GROUP_SID_INDEX
].sid
= *domain_sid
;
255 sid_append_rid(&user_info_dc
->sids
[PRIMARY_GROUP_SID_INDEX
].sid
, DOMAIN_RID_USERS
);
256 user_info_dc
->sids
[PRIMARY_GROUP_SID_INDEX
].attrs
= SE_GROUP_DEFAULT_FLAGS
;
258 /* Add the primary group again. */
259 user_info_dc
->sids
[2] = user_info_dc
->sids
[PRIMARY_GROUP_SID_INDEX
];
261 user_info_dc
->sids
[3].sid
= global_sid_Builtin_Administrators
;
262 user_info_dc
->sids
[3].attrs
= SE_GROUP_DEFAULT_FLAGS
;
264 user_info_dc
->sids
[4].sid
= *domain_sid
;
265 sid_append_rid(&user_info_dc
->sids
[4].sid
, DOMAIN_RID_ADMINS
);
266 user_info_dc
->sids
[4].attrs
= SE_GROUP_DEFAULT_FLAGS
;
267 user_info_dc
->sids
[5].sid
= *domain_sid
;
268 sid_append_rid(&user_info_dc
->sids
[5].sid
, DOMAIN_RID_ENTERPRISE_ADMINS
);
269 user_info_dc
->sids
[5].attrs
= SE_GROUP_DEFAULT_FLAGS
;
270 user_info_dc
->sids
[6].sid
= *domain_sid
;
271 sid_append_rid(&user_info_dc
->sids
[6].sid
, DOMAIN_RID_POLICY_ADMINS
);
272 user_info_dc
->sids
[6].attrs
= SE_GROUP_DEFAULT_FLAGS
;
273 user_info_dc
->sids
[7].sid
= *domain_sid
;
274 sid_append_rid(&user_info_dc
->sids
[7].sid
, DOMAIN_RID_SCHEMA_ADMINS
);
275 user_info_dc
->sids
[7].attrs
= SE_GROUP_DEFAULT_FLAGS
;
277 /* What should the session key be?*/
278 user_info_dc
->user_session_key
= data_blob_talloc(user_info_dc
, NULL
, 16);
279 if (user_info_dc
->user_session_key
.data
== NULL
) {
280 talloc_free(user_info_dc
);
281 return NT_STATUS_NO_MEMORY
;
284 user_info_dc
->lm_session_key
= data_blob_talloc(user_info_dc
, NULL
, 16);
285 if (user_info_dc
->lm_session_key
.data
== NULL
) {
286 talloc_free(user_info_dc
);
287 return NT_STATUS_NO_MEMORY
;
290 data_blob_clear(&user_info_dc
->user_session_key
);
291 data_blob_clear(&user_info_dc
->lm_session_key
);
293 user_info_dc
->info
= info
= talloc_zero(user_info_dc
, struct auth_user_info
);
294 if (user_info_dc
->info
== NULL
) {
295 talloc_free(user_info_dc
);
296 return NT_STATUS_NO_MEMORY
;
299 info
->account_name
= talloc_strdup(info
, "Administrator");
300 if (info
->account_name
== NULL
) {
301 talloc_free(user_info_dc
);
302 return NT_STATUS_NO_MEMORY
;
305 info
->domain_name
= talloc_strdup(info
, domain_name
);
306 if (info
->domain_name
== NULL
) {
307 talloc_free(user_info_dc
);
308 return NT_STATUS_NO_MEMORY
;
311 info
->full_name
= talloc_strdup(info
, "Administrator");
312 if (info
->full_name
== NULL
) {
313 talloc_free(user_info_dc
);
314 return NT_STATUS_NO_MEMORY
;
317 info
->logon_script
= talloc_strdup(info
, "");
318 if (info
->logon_script
== NULL
) {
319 talloc_free(user_info_dc
);
320 return NT_STATUS_NO_MEMORY
;
323 info
->profile_path
= talloc_strdup(info
, "");
324 if (info
->profile_path
== NULL
) {
325 talloc_free(user_info_dc
);
326 return NT_STATUS_NO_MEMORY
;
329 info
->home_directory
= talloc_strdup(info
, "");
330 if (info
->home_directory
== NULL
) {
331 talloc_free(user_info_dc
);
332 return NT_STATUS_NO_MEMORY
;
335 info
->home_drive
= talloc_strdup(info
, "");
336 if (info
->home_drive
== NULL
) {
337 talloc_free(user_info_dc
);
338 return NT_STATUS_NO_MEMORY
;
341 info
->logon_server
= talloc_strdup(info
, netbios_name
);
342 if (info
->logon_server
== NULL
) {
343 talloc_free(user_info_dc
);
344 return NT_STATUS_NO_MEMORY
;
347 info
->last_logon
= 0;
348 info
->last_logoff
= 0;
349 info
->acct_expiry
= 0;
350 info
->last_password_change
= 0;
351 info
->allow_password_change
= 0;
352 info
->force_password_change
= 0;
354 info
->logon_count
= 0;
355 info
->bad_password_count
= 0;
357 info
->acct_flags
= ACB_NORMAL
;
359 info
->user_flags
= 0;
361 *_user_info_dc
= user_info_dc
;
366 static NTSTATUS
auth_domain_admin_session_info(TALLOC_CTX
*parent_ctx
,
367 struct loadparm_context
*lp_ctx
,
368 struct dom_sid
*domain_sid
,
369 struct auth_session_info
**session_info
)
372 struct auth_user_info_dc
*user_info_dc
= NULL
;
373 TALLOC_CTX
*mem_ctx
= talloc_new(parent_ctx
);
375 NT_STATUS_HAVE_NO_MEMORY(mem_ctx
);
377 nt_status
= auth_domain_admin_user_info_dc(mem_ctx
,
378 lpcfg_netbios_name(lp_ctx
),
379 lpcfg_workgroup(lp_ctx
),
382 if (!NT_STATUS_IS_OK(nt_status
)) {
383 talloc_free(mem_ctx
);
387 nt_status
= auth_generate_session_info(mem_ctx
,
391 AUTH_SESSION_INFO_SIMPLE_PRIVILEGES
|AUTH_SESSION_INFO_AUTHENTICATED
|AUTH_SESSION_INFO_DEFAULT_GROUPS
,
393 /* There is already a reference between the session_info and user_info_dc */
394 if (NT_STATUS_IS_OK(nt_status
)) {
395 talloc_steal(parent_ctx
, *session_info
);
397 talloc_free(mem_ctx
);
401 _PUBLIC_
struct auth_session_info
*admin_session(TALLOC_CTX
*mem_ctx
, struct loadparm_context
*lp_ctx
, struct dom_sid
*domain_sid
)
404 struct auth_session_info
*session_info
= NULL
;
405 nt_status
= auth_domain_admin_session_info(mem_ctx
,
409 if (!NT_STATUS_IS_OK(nt_status
)) {
415 _PUBLIC_ NTSTATUS
auth_anonymous_session_info(TALLOC_CTX
*parent_ctx
,
416 struct loadparm_context
*lp_ctx
,
417 struct auth_session_info
**_session_info
)
420 struct auth_user_info_dc
*user_info_dc
= NULL
;
421 struct auth_session_info
*session_info
= NULL
;
422 TALLOC_CTX
*mem_ctx
= talloc_new(parent_ctx
);
425 if (mem_ctx
== NULL
) {
426 return NT_STATUS_NO_MEMORY
;
429 nt_status
= auth_anonymous_user_info_dc(mem_ctx
,
430 lpcfg_netbios_name(lp_ctx
),
432 if (!NT_STATUS_IS_OK(nt_status
)) {
433 talloc_free(mem_ctx
);
437 /* references the user_info_dc into the session_info */
438 nt_status
= auth_generate_session_info(parent_ctx
,
442 AUTH_SESSION_INFO_SIMPLE_PRIVILEGES
,
444 talloc_free(mem_ctx
);
446 NT_STATUS_NOT_OK_RETURN(nt_status
);
448 session_info
->credentials
= cli_credentials_init(session_info
);
449 if (!session_info
->credentials
) {
450 talloc_free(session_info
);
451 return NT_STATUS_NO_MEMORY
;
454 ok
= cli_credentials_set_conf(session_info
->credentials
, lp_ctx
);
456 talloc_free(session_info
);
457 return NT_STATUS_INTERNAL_ERROR
;
459 cli_credentials_set_anonymous(session_info
->credentials
);
461 *_session_info
= session_info
;
466 _PUBLIC_ NTSTATUS
auth_anonymous_user_info_dc(TALLOC_CTX
*mem_ctx
,
467 const char *netbios_name
,
468 struct auth_user_info_dc
**_user_info_dc
)
470 struct auth_user_info_dc
*user_info_dc
;
471 struct auth_user_info
*info
;
472 user_info_dc
= talloc_zero(mem_ctx
, struct auth_user_info_dc
);
473 NT_STATUS_HAVE_NO_MEMORY(user_info_dc
);
475 /* This returns a pointer to a struct dom_sid, which is the
476 * same as a 1 element list of struct dom_sid */
477 user_info_dc
->num_sids
= 1;
478 user_info_dc
->sids
= talloc(user_info_dc
, struct auth_SidAttr
);
479 if (user_info_dc
->sids
== NULL
) {
480 talloc_free(user_info_dc
);
481 return NT_STATUS_NO_MEMORY
;
484 user_info_dc
->sids
->sid
= global_sid_Anonymous
;
485 user_info_dc
->sids
->attrs
= SE_GROUP_DEFAULT_FLAGS
;
487 /* annoying, but the Anonymous really does have a session key... */
488 user_info_dc
->user_session_key
= data_blob_talloc(user_info_dc
, NULL
, 16);
489 if (user_info_dc
->user_session_key
.data
== NULL
) {
490 talloc_free(user_info_dc
);
491 return NT_STATUS_NO_MEMORY
;
494 user_info_dc
->lm_session_key
= data_blob_talloc(user_info_dc
, NULL
, 16);
495 if (user_info_dc
->lm_session_key
.data
== NULL
) {
496 talloc_free(user_info_dc
);
497 return NT_STATUS_NO_MEMORY
;
500 /* and it is all zeros! */
501 data_blob_clear(&user_info_dc
->user_session_key
);
502 data_blob_clear(&user_info_dc
->lm_session_key
);
504 user_info_dc
->info
= info
= talloc_zero(user_info_dc
, struct auth_user_info
);
505 if (user_info_dc
->info
== NULL
) {
506 talloc_free(user_info_dc
);
507 return NT_STATUS_NO_MEMORY
;
510 info
->account_name
= talloc_strdup(info
, "ANONYMOUS LOGON");
511 if (info
->account_name
== NULL
) {
512 talloc_free(user_info_dc
);
513 return NT_STATUS_NO_MEMORY
;
516 info
->domain_name
= talloc_strdup(info
, "NT AUTHORITY");
517 if (info
->domain_name
== NULL
) {
518 talloc_free(user_info_dc
);
519 return NT_STATUS_NO_MEMORY
;
522 info
->full_name
= talloc_strdup(info
, "Anonymous Logon");
523 if (info
->full_name
== NULL
) {
524 talloc_free(user_info_dc
);
525 return NT_STATUS_NO_MEMORY
;
528 info
->logon_script
= talloc_strdup(info
, "");
529 if (info
->logon_script
== NULL
) {
530 talloc_free(user_info_dc
);
531 return NT_STATUS_NO_MEMORY
;
534 info
->profile_path
= talloc_strdup(info
, "");
535 if (info
->profile_path
== NULL
) {
536 talloc_free(user_info_dc
);
537 return NT_STATUS_NO_MEMORY
;
540 info
->home_directory
= talloc_strdup(info
, "");
541 if (info
->home_directory
== NULL
) {
542 talloc_free(user_info_dc
);
543 return NT_STATUS_NO_MEMORY
;
546 info
->home_drive
= talloc_strdup(info
, "");
547 if (info
->home_drive
== NULL
) {
548 talloc_free(user_info_dc
);
549 return NT_STATUS_NO_MEMORY
;
552 info
->logon_server
= talloc_strdup(info
, netbios_name
);
553 if (info
->logon_server
== NULL
) {
554 talloc_free(user_info_dc
);
555 return NT_STATUS_NO_MEMORY
;
558 info
->last_logon
= 0;
559 info
->last_logoff
= 0;
560 info
->acct_expiry
= 0;
561 info
->last_password_change
= 0;
562 info
->allow_password_change
= 0;
563 info
->force_password_change
= 0;
565 info
->logon_count
= 0;
566 info
->bad_password_count
= 0;
568 info
->acct_flags
= ACB_NORMAL
;
570 /* The user is not authenticated. */
571 info
->user_flags
= NETLOGON_GUEST
;
573 *_user_info_dc
= user_info_dc
;