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, NULL, NULL, user_info_dc, AUTH_SESSION_INFO_SIMPLE_PRIVILEGES, &session_info);
98 NT_STATUS_NOT_OK_RETURN(nt_status);
100 session_info->credentials = cli_credentials_init(session_info);
101 if (!session_info->credentials) {
102 return NT_STATUS_NO_MEMORY;
105 ok = cli_credentials_set_conf(session_info->credentials, lp_ctx);
107 return NT_STATUS_INTERNAL_ERROR;
110 cli_credentials_set_machine_account_pending(session_info->credentials, lp_ctx);
111 *_session_info = session_info;
116 NTSTATUS auth_system_user_info_dc(TALLOC_CTX *mem_ctx, const char *netbios_name,
117 struct auth_user_info_dc **_user_info_dc)
119 struct auth_user_info_dc *user_info_dc;
120 struct auth_user_info *info;
122 user_info_dc = talloc_zero(mem_ctx, struct auth_user_info_dc);
123 NT_STATUS_HAVE_NO_MEMORY(user_info_dc);
125 /* This returns a pointer to a struct dom_sid, which is the
126 * same as a 1 element list of struct dom_sid */
127 user_info_dc->num_sids = 1;
128 user_info_dc->sids = talloc(user_info_dc, struct auth_SidAttr);
129 if (user_info_dc->sids == NULL) {
130 talloc_free(user_info_dc);
131 return NT_STATUS_NO_MEMORY;
134 user_info_dc->sids->sid = global_sid_System;
135 user_info_dc->sids->attrs = SE_GROUP_DEFAULT_FLAGS;
137 /* annoying, but the Anonymous really does have a session key,
138 and it is all zeros! */
139 user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16);
140 if (user_info_dc->user_session_key.data == NULL) {
141 talloc_free(user_info_dc);
142 return NT_STATUS_NO_MEMORY;
145 user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16);
146 if (user_info_dc->lm_session_key.data == NULL) {
147 talloc_free(user_info_dc);
148 return NT_STATUS_NO_MEMORY;
151 data_blob_clear(&user_info_dc->user_session_key);
152 data_blob_clear(&user_info_dc->lm_session_key);
154 user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
155 if (user_info_dc->info == NULL) {
156 talloc_free(user_info_dc);
157 return NT_STATUS_NO_MEMORY;
160 info->account_name = talloc_strdup(info, "SYSTEM");
161 if (info->account_name == NULL) {
162 talloc_free(user_info_dc);
163 return NT_STATUS_NO_MEMORY;
166 info->domain_name = talloc_strdup(info, "NT AUTHORITY");
167 if (info->domain_name == NULL) {
168 talloc_free(user_info_dc);
169 return NT_STATUS_NO_MEMORY;
172 info->full_name = talloc_strdup(info, "System");
173 if (info->full_name == NULL) {
174 talloc_free(user_info_dc);
175 return NT_STATUS_NO_MEMORY;
178 info->logon_script = talloc_strdup(info, "");
179 if (info->logon_script == NULL) {
180 talloc_free(user_info_dc);
181 return NT_STATUS_NO_MEMORY;
184 info->profile_path = talloc_strdup(info, "");
185 if (info->profile_path == NULL) {
186 talloc_free(user_info_dc);
187 return NT_STATUS_NO_MEMORY;
190 info->home_directory = talloc_strdup(info, "");
191 if (info->home_directory == NULL) {
192 talloc_free(user_info_dc);
193 return NT_STATUS_NO_MEMORY;
196 info->home_drive = talloc_strdup(info, "");
197 if (info->home_drive == NULL) {
198 talloc_free(user_info_dc);
199 return NT_STATUS_NO_MEMORY;
202 info->logon_server = talloc_strdup(info, netbios_name);
203 if (info->logon_server == NULL) {
204 talloc_free(user_info_dc);
205 return NT_STATUS_NO_MEMORY;
208 info->last_logon = 0;
209 info->last_logoff = 0;
210 info->acct_expiry = 0;
211 info->last_password_change = 0;
212 info->allow_password_change = 0;
213 info->force_password_change = 0;
215 info->logon_count = 0;
216 info->bad_password_count = 0;
218 info->acct_flags = ACB_NORMAL;
220 info->user_flags = 0;
222 *_user_info_dc = user_info_dc;
228 static NTSTATUS auth_domain_admin_user_info_dc(TALLOC_CTX *mem_ctx,
229 const char *netbios_name,
230 const char *domain_name,
231 struct dom_sid *domain_sid,
232 struct auth_user_info_dc **_user_info_dc)
234 struct auth_user_info_dc *user_info_dc;
235 struct auth_user_info *info;
237 user_info_dc = talloc_zero(mem_ctx, struct auth_user_info_dc);
238 NT_STATUS_HAVE_NO_MEMORY(user_info_dc);
240 user_info_dc->num_sids = 8;
241 user_info_dc->sids = talloc_array(user_info_dc, struct auth_SidAttr, user_info_dc->num_sids);
243 user_info_dc->sids[PRIMARY_USER_SID_INDEX].sid = *domain_sid;
244 sid_append_rid(&user_info_dc->sids[PRIMARY_USER_SID_INDEX].sid, DOMAIN_RID_ADMINISTRATOR);
245 user_info_dc->sids[PRIMARY_USER_SID_INDEX].attrs = SE_GROUP_DEFAULT_FLAGS;
247 user_info_dc->sids[PRIMARY_GROUP_SID_INDEX].sid = *domain_sid;
248 sid_append_rid(&user_info_dc->sids[PRIMARY_GROUP_SID_INDEX].sid, DOMAIN_RID_USERS);
249 user_info_dc->sids[PRIMARY_GROUP_SID_INDEX].attrs = SE_GROUP_DEFAULT_FLAGS;
251 /* Add the primary group again. */
252 user_info_dc->sids[2] = user_info_dc->sids[PRIMARY_GROUP_SID_INDEX];
254 user_info_dc->sids[3].sid = global_sid_Builtin_Administrators;
255 user_info_dc->sids[3].attrs = SE_GROUP_DEFAULT_FLAGS;
257 user_info_dc->sids[4].sid = *domain_sid;
258 sid_append_rid(&user_info_dc->sids[4].sid, DOMAIN_RID_ADMINS);
259 user_info_dc->sids[4].attrs = SE_GROUP_DEFAULT_FLAGS;
260 user_info_dc->sids[5].sid = *domain_sid;
261 sid_append_rid(&user_info_dc->sids[5].sid, DOMAIN_RID_ENTERPRISE_ADMINS);
262 user_info_dc->sids[5].attrs = SE_GROUP_DEFAULT_FLAGS;
263 user_info_dc->sids[6].sid = *domain_sid;
264 sid_append_rid(&user_info_dc->sids[6].sid, DOMAIN_RID_POLICY_ADMINS);
265 user_info_dc->sids[6].attrs = SE_GROUP_DEFAULT_FLAGS;
266 user_info_dc->sids[7].sid = *domain_sid;
267 sid_append_rid(&user_info_dc->sids[7].sid, DOMAIN_RID_SCHEMA_ADMINS);
268 user_info_dc->sids[7].attrs = SE_GROUP_DEFAULT_FLAGS;
270 /* What should the session key be?*/
271 user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16);
272 if (user_info_dc->user_session_key.data == NULL) {
273 talloc_free(user_info_dc);
274 return NT_STATUS_NO_MEMORY;
277 user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16);
278 if (user_info_dc->lm_session_key.data == NULL) {
279 talloc_free(user_info_dc);
280 return NT_STATUS_NO_MEMORY;
283 data_blob_clear(&user_info_dc->user_session_key);
284 data_blob_clear(&user_info_dc->lm_session_key);
286 user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
287 if (user_info_dc->info == NULL) {
288 talloc_free(user_info_dc);
289 return NT_STATUS_NO_MEMORY;
292 info->account_name = talloc_strdup(info, "Administrator");
293 if (info->account_name == NULL) {
294 talloc_free(user_info_dc);
295 return NT_STATUS_NO_MEMORY;
298 info->domain_name = talloc_strdup(info, domain_name);
299 if (info->domain_name == NULL) {
300 talloc_free(user_info_dc);
301 return NT_STATUS_NO_MEMORY;
304 info->full_name = talloc_strdup(info, "Administrator");
305 if (info->full_name == NULL) {
306 talloc_free(user_info_dc);
307 return NT_STATUS_NO_MEMORY;
310 info->logon_script = talloc_strdup(info, "");
311 if (info->logon_script == NULL) {
312 talloc_free(user_info_dc);
313 return NT_STATUS_NO_MEMORY;
316 info->profile_path = talloc_strdup(info, "");
317 if (info->profile_path == NULL) {
318 talloc_free(user_info_dc);
319 return NT_STATUS_NO_MEMORY;
322 info->home_directory = talloc_strdup(info, "");
323 if (info->home_directory == NULL) {
324 talloc_free(user_info_dc);
325 return NT_STATUS_NO_MEMORY;
328 info->home_drive = talloc_strdup(info, "");
329 if (info->home_drive == NULL) {
330 talloc_free(user_info_dc);
331 return NT_STATUS_NO_MEMORY;
334 info->logon_server = talloc_strdup(info, netbios_name);
335 if (info->logon_server == NULL) {
336 talloc_free(user_info_dc);
337 return NT_STATUS_NO_MEMORY;
340 info->last_logon = 0;
341 info->last_logoff = 0;
342 info->acct_expiry = 0;
343 info->last_password_change = 0;
344 info->allow_password_change = 0;
345 info->force_password_change = 0;
347 info->logon_count = 0;
348 info->bad_password_count = 0;
350 info->acct_flags = ACB_NORMAL;
352 info->user_flags = 0;
354 *_user_info_dc = user_info_dc;
359 static NTSTATUS auth_domain_admin_session_info(TALLOC_CTX *parent_ctx,
360 struct loadparm_context *lp_ctx,
361 struct dom_sid *domain_sid,
362 struct auth_session_info **session_info)
365 struct auth_user_info_dc *user_info_dc = NULL;
366 TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
368 NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
370 nt_status = auth_domain_admin_user_info_dc(mem_ctx, lpcfg_netbios_name(lp_ctx),
371 lpcfg_workgroup(lp_ctx), domain_sid,
373 if (!NT_STATUS_IS_OK(nt_status)) {
374 talloc_free(mem_ctx);
378 nt_status = auth_generate_session_info(mem_ctx, NULL, NULL, user_info_dc,
379 AUTH_SESSION_INFO_SIMPLE_PRIVILEGES|AUTH_SESSION_INFO_AUTHENTICATED|AUTH_SESSION_INFO_DEFAULT_GROUPS,
381 /* There is already a reference between the session_info and user_info_dc */
382 if (NT_STATUS_IS_OK(nt_status)) {
383 talloc_steal(parent_ctx, *session_info);
385 talloc_free(mem_ctx);
389 _PUBLIC_ struct auth_session_info *admin_session(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct dom_sid *domain_sid)
392 struct auth_session_info *session_info = NULL;
393 nt_status = auth_domain_admin_session_info(mem_ctx,
397 if (!NT_STATUS_IS_OK(nt_status)) {
403 _PUBLIC_ NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx,
404 struct loadparm_context *lp_ctx,
405 struct auth_session_info **_session_info)
408 struct auth_user_info_dc *user_info_dc = NULL;
409 struct auth_session_info *session_info = NULL;
410 TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
413 nt_status = auth_anonymous_user_info_dc(mem_ctx,
414 lpcfg_netbios_name(lp_ctx),
416 if (!NT_STATUS_IS_OK(nt_status)) {
417 talloc_free(mem_ctx);
421 /* references the user_info_dc into the session_info */
422 nt_status = auth_generate_session_info(parent_ctx, NULL, NULL, user_info_dc, AUTH_SESSION_INFO_SIMPLE_PRIVILEGES, &session_info);
423 talloc_free(mem_ctx);
425 NT_STATUS_NOT_OK_RETURN(nt_status);
427 session_info->credentials = cli_credentials_init(session_info);
428 if (!session_info->credentials) {
429 return NT_STATUS_NO_MEMORY;
432 ok = cli_credentials_set_conf(session_info->credentials, lp_ctx);
434 return NT_STATUS_INTERNAL_ERROR;
436 cli_credentials_set_anonymous(session_info->credentials);
438 *_session_info = session_info;
443 _PUBLIC_ NTSTATUS auth_anonymous_user_info_dc(TALLOC_CTX *mem_ctx,
444 const char *netbios_name,
445 struct auth_user_info_dc **_user_info_dc)
447 struct auth_user_info_dc *user_info_dc;
448 struct auth_user_info *info;
449 user_info_dc = talloc_zero(mem_ctx, struct auth_user_info_dc);
450 NT_STATUS_HAVE_NO_MEMORY(user_info_dc);
452 /* This returns a pointer to a struct dom_sid, which is the
453 * same as a 1 element list of struct dom_sid */
454 user_info_dc->num_sids = 1;
455 user_info_dc->sids = talloc(user_info_dc, struct auth_SidAttr);
456 if (user_info_dc->sids == NULL) {
457 talloc_free(user_info_dc);
458 return NT_STATUS_NO_MEMORY;
461 user_info_dc->sids->sid = global_sid_Anonymous;
462 user_info_dc->sids->attrs = SE_GROUP_DEFAULT_FLAGS;
464 /* annoying, but the Anonymous really does have a session key... */
465 user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16);
466 if (user_info_dc->user_session_key.data == NULL) {
467 talloc_free(user_info_dc);
468 return NT_STATUS_NO_MEMORY;
471 user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16);
472 if (user_info_dc->lm_session_key.data == NULL) {
473 talloc_free(user_info_dc);
474 return NT_STATUS_NO_MEMORY;
477 /* and it is all zeros! */
478 data_blob_clear(&user_info_dc->user_session_key);
479 data_blob_clear(&user_info_dc->lm_session_key);
481 user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
482 if (user_info_dc->info == NULL) {
483 talloc_free(user_info_dc);
484 return NT_STATUS_NO_MEMORY;
487 info->account_name = talloc_strdup(info, "ANONYMOUS LOGON");
488 if (info->account_name == NULL) {
489 talloc_free(user_info_dc);
490 return NT_STATUS_NO_MEMORY;
493 info->domain_name = talloc_strdup(info, "NT AUTHORITY");
494 if (info->domain_name == NULL) {
495 talloc_free(user_info_dc);
496 return NT_STATUS_NO_MEMORY;
499 info->full_name = talloc_strdup(info, "Anonymous Logon");
500 if (info->full_name == NULL) {
501 talloc_free(user_info_dc);
502 return NT_STATUS_NO_MEMORY;
505 info->logon_script = talloc_strdup(info, "");
506 if (info->logon_script == NULL) {
507 talloc_free(user_info_dc);
508 return NT_STATUS_NO_MEMORY;
511 info->profile_path = talloc_strdup(info, "");
512 if (info->profile_path == NULL) {
513 talloc_free(user_info_dc);
514 return NT_STATUS_NO_MEMORY;
517 info->home_directory = talloc_strdup(info, "");
518 if (info->home_directory == NULL) {
519 talloc_free(user_info_dc);
520 return NT_STATUS_NO_MEMORY;
523 info->home_drive = talloc_strdup(info, "");
524 if (info->home_drive == NULL) {
525 talloc_free(user_info_dc);
526 return NT_STATUS_NO_MEMORY;
529 info->logon_server = talloc_strdup(info, netbios_name);
530 if (info->logon_server == NULL) {
531 talloc_free(user_info_dc);
532 return NT_STATUS_NO_MEMORY;
535 info->last_logon = 0;
536 info->last_logoff = 0;
537 info->acct_expiry = 0;
538 info->last_password_change = 0;
539 info->allow_password_change = 0;
540 info->force_password_change = 0;
542 info->logon_count = 0;
543 info->bad_password_count = 0;
545 info->acct_flags = ACB_NORMAL;
547 /* The user is not authenticated. */
548 info->user_flags = NETLOGON_GUEST;
550 *_user_info_dc = user_info_dc;