s3:utils: Handle the domain before username and password
[samba.git] / source4 / auth / system_session.c
blob31a45174f0ff9655bb9e27f84207b7b86028ad90
1 /*
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/>.
24 #include "includes.h"
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"
32 #undef DBGC_CLASS
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)
40 return -1;
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
46 */
47 _PUBLIC_ struct auth_session_info *system_session(struct loadparm_context *lp_ctx)
49 static struct auth_session_info *static_session;
50 NTSTATUS nt_status;
52 if (static_session) {
53 return static_session;
57 * Use NULL here, not the autofree context for this
58 * static pointer. The destructor prevents freeing this
59 * memory anyway.
61 nt_status = auth_system_session_info(NULL,
62 lp_ctx,
63 &static_session);
64 if (!NT_STATUS_IS_OK(nt_status)) {
65 TALLOC_FREE(static_session);
66 return NULL;
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)
76 NTSTATUS nt_status;
77 struct auth_user_info_dc *user_info_dc = NULL;
78 struct auth_session_info *session_info = NULL;
79 TALLOC_CTX *mem_ctx = NULL;
80 bool ok;
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),
88 &user_info_dc);
89 if (!NT_STATUS_IS_OK(nt_status)) {
90 talloc_free(mem_ctx);
91 return nt_status;
94 /* references the user_info_dc into the session_info */
95 nt_status = auth_generate_session_info(parent_ctx,
96 lp_ctx,
97 NULL /* sam_ctx */,
98 user_info_dc,
99 AUTH_SESSION_INFO_SIMPLE_PRIVILEGES,
100 &session_info);
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);
112 if (!ok) {
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;
120 return NT_STATUS_OK;
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;
231 return NT_STATUS_OK;
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;
363 return NT_STATUS_OK;
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)
371 NTSTATUS nt_status;
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),
380 domain_sid,
381 &user_info_dc);
382 if (!NT_STATUS_IS_OK(nt_status)) {
383 talloc_free(mem_ctx);
384 return nt_status;
387 nt_status = auth_generate_session_info(mem_ctx,
388 lp_ctx,
389 NULL /* sam_ctx */,
390 user_info_dc,
391 AUTH_SESSION_INFO_SIMPLE_PRIVILEGES|AUTH_SESSION_INFO_AUTHENTICATED|AUTH_SESSION_INFO_DEFAULT_GROUPS,
392 session_info);
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);
398 return nt_status;
401 _PUBLIC_ struct auth_session_info *admin_session(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct dom_sid *domain_sid)
403 NTSTATUS nt_status;
404 struct auth_session_info *session_info = NULL;
405 nt_status = auth_domain_admin_session_info(mem_ctx,
406 lp_ctx,
407 domain_sid,
408 &session_info);
409 if (!NT_STATUS_IS_OK(nt_status)) {
410 return NULL;
412 return session_info;
415 _PUBLIC_ NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx,
416 struct loadparm_context *lp_ctx,
417 struct auth_session_info **_session_info)
419 NTSTATUS nt_status;
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);
423 bool ok;
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),
431 &user_info_dc);
432 if (!NT_STATUS_IS_OK(nt_status)) {
433 talloc_free(mem_ctx);
434 return nt_status;
437 /* references the user_info_dc into the session_info */
438 nt_status = auth_generate_session_info(parent_ctx,
439 lp_ctx,
440 NULL /* sam_ctx */,
441 user_info_dc,
442 AUTH_SESSION_INFO_SIMPLE_PRIVILEGES,
443 &session_info);
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);
455 if (!ok) {
456 talloc_free(session_info);
457 return NT_STATUS_INTERNAL_ERROR;
459 cli_credentials_set_anonymous(session_info->credentials);
461 *_session_info = session_info;
463 return NT_STATUS_OK;
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;
575 return NT_STATUS_OK;