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 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->sids);
131 user_info_dc->sids->sid = global_sid_System;
132 user_info_dc->sids->attrs = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;
134 /* annoying, but the Anonymous really does have a session key,
135 and it is all zeros! */
136 user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16);
137 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->user_session_key.data);
139 user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16);
140 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->lm_session_key.data);
142 data_blob_clear(&user_info_dc->user_session_key);
143 data_blob_clear(&user_info_dc->lm_session_key);
145 user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
146 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info);
148 info->account_name = talloc_strdup(info, "SYSTEM");
149 NT_STATUS_HAVE_NO_MEMORY(info->account_name);
151 info->domain_name = talloc_strdup(info, "NT AUTHORITY");
152 NT_STATUS_HAVE_NO_MEMORY(info->domain_name);
154 info->full_name = talloc_strdup(info, "System");
155 NT_STATUS_HAVE_NO_MEMORY(info->full_name);
157 info->logon_script = talloc_strdup(info, "");
158 NT_STATUS_HAVE_NO_MEMORY(info->logon_script);
160 info->profile_path = talloc_strdup(info, "");
161 NT_STATUS_HAVE_NO_MEMORY(info->profile_path);
163 info->home_directory = talloc_strdup(info, "");
164 NT_STATUS_HAVE_NO_MEMORY(info->home_directory);
166 info->home_drive = talloc_strdup(info, "");
167 NT_STATUS_HAVE_NO_MEMORY(info->home_drive);
169 info->logon_server = talloc_strdup(info, netbios_name);
170 NT_STATUS_HAVE_NO_MEMORY(info->logon_server);
172 info->last_logon = 0;
173 info->last_logoff = 0;
174 info->acct_expiry = 0;
175 info->last_password_change = 0;
176 info->allow_password_change = 0;
177 info->force_password_change = 0;
179 info->logon_count = 0;
180 info->bad_password_count = 0;
182 info->acct_flags = ACB_NORMAL;
184 info->user_flags = 0;
186 *_user_info_dc = user_info_dc;
192 static NTSTATUS auth_domain_admin_user_info_dc(TALLOC_CTX *mem_ctx,
193 const char *netbios_name,
194 const char *domain_name,
195 struct dom_sid *domain_sid,
196 struct auth_user_info_dc **_user_info_dc)
198 struct auth_user_info_dc *user_info_dc;
199 struct auth_user_info *info;
201 user_info_dc = talloc_zero(mem_ctx, struct auth_user_info_dc);
202 NT_STATUS_HAVE_NO_MEMORY(user_info_dc);
204 user_info_dc->num_sids = 7;
205 user_info_dc->sids = talloc_array(user_info_dc, struct auth_SidAttr, user_info_dc->num_sids);
207 user_info_dc->sids[PRIMARY_USER_SID_INDEX].sid = *domain_sid;
208 sid_append_rid(&user_info_dc->sids[PRIMARY_USER_SID_INDEX].sid, DOMAIN_RID_ADMINISTRATOR);
209 user_info_dc->sids[PRIMARY_USER_SID_INDEX].attrs
210 = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;
212 user_info_dc->sids[PRIMARY_GROUP_SID_INDEX].sid = *domain_sid;
213 sid_append_rid(&user_info_dc->sids[PRIMARY_GROUP_SID_INDEX].sid, DOMAIN_RID_USERS);
214 user_info_dc->sids[PRIMARY_GROUP_SID_INDEX].attrs
215 = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;
217 user_info_dc->sids[2].sid = global_sid_Builtin_Administrators;
218 user_info_dc->sids[2].attrs
219 = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;
221 user_info_dc->sids[3].sid = *domain_sid;
222 sid_append_rid(&user_info_dc->sids[3].sid, DOMAIN_RID_ADMINS);
223 user_info_dc->sids[3].attrs
224 = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;
225 user_info_dc->sids[4].sid = *domain_sid;
226 sid_append_rid(&user_info_dc->sids[4].sid, DOMAIN_RID_ENTERPRISE_ADMINS);
227 user_info_dc->sids[4].attrs
228 = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;
229 user_info_dc->sids[5].sid = *domain_sid;
230 sid_append_rid(&user_info_dc->sids[5].sid, DOMAIN_RID_POLICY_ADMINS);
231 user_info_dc->sids[5].attrs
232 = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;
233 user_info_dc->sids[6].sid = *domain_sid;
234 sid_append_rid(&user_info_dc->sids[6].sid, DOMAIN_RID_SCHEMA_ADMINS);
235 user_info_dc->sids[6].attrs
236 = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;
238 /* What should the session key be?*/
239 user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16);
240 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->user_session_key.data);
242 user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16);
243 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->lm_session_key.data);
245 data_blob_clear(&user_info_dc->user_session_key);
246 data_blob_clear(&user_info_dc->lm_session_key);
248 user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
249 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info);
251 info->account_name = talloc_strdup(info, "Administrator");
252 NT_STATUS_HAVE_NO_MEMORY(info->account_name);
254 info->domain_name = talloc_strdup(info, domain_name);
255 NT_STATUS_HAVE_NO_MEMORY(info->domain_name);
257 info->full_name = talloc_strdup(info, "Administrator");
258 NT_STATUS_HAVE_NO_MEMORY(info->full_name);
260 info->logon_script = talloc_strdup(info, "");
261 NT_STATUS_HAVE_NO_MEMORY(info->logon_script);
263 info->profile_path = talloc_strdup(info, "");
264 NT_STATUS_HAVE_NO_MEMORY(info->profile_path);
266 info->home_directory = talloc_strdup(info, "");
267 NT_STATUS_HAVE_NO_MEMORY(info->home_directory);
269 info->home_drive = talloc_strdup(info, "");
270 NT_STATUS_HAVE_NO_MEMORY(info->home_drive);
272 info->logon_server = talloc_strdup(info, netbios_name);
273 NT_STATUS_HAVE_NO_MEMORY(info->logon_server);
275 info->last_logon = 0;
276 info->last_logoff = 0;
277 info->acct_expiry = 0;
278 info->last_password_change = 0;
279 info->allow_password_change = 0;
280 info->force_password_change = 0;
282 info->logon_count = 0;
283 info->bad_password_count = 0;
285 info->acct_flags = ACB_NORMAL;
287 info->user_flags = 0;
289 *_user_info_dc = user_info_dc;
294 static NTSTATUS auth_domain_admin_session_info(TALLOC_CTX *parent_ctx,
295 struct loadparm_context *lp_ctx,
296 struct dom_sid *domain_sid,
297 struct auth_session_info **session_info)
300 struct auth_user_info_dc *user_info_dc = NULL;
301 TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
303 NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
305 nt_status = auth_domain_admin_user_info_dc(mem_ctx, lpcfg_netbios_name(lp_ctx),
306 lpcfg_workgroup(lp_ctx), domain_sid,
308 if (!NT_STATUS_IS_OK(nt_status)) {
309 talloc_free(mem_ctx);
313 nt_status = auth_generate_session_info(mem_ctx, NULL, NULL, user_info_dc,
314 AUTH_SESSION_INFO_SIMPLE_PRIVILEGES|AUTH_SESSION_INFO_AUTHENTICATED|AUTH_SESSION_INFO_DEFAULT_GROUPS,
316 /* There is already a reference between the sesion_info and user_info_dc */
317 if (NT_STATUS_IS_OK(nt_status)) {
318 talloc_steal(parent_ctx, *session_info);
320 talloc_free(mem_ctx);
324 _PUBLIC_ struct auth_session_info *admin_session(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct dom_sid *domain_sid)
327 struct auth_session_info *session_info = NULL;
328 nt_status = auth_domain_admin_session_info(mem_ctx,
332 if (!NT_STATUS_IS_OK(nt_status)) {
338 _PUBLIC_ NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx,
339 struct loadparm_context *lp_ctx,
340 struct auth_session_info **_session_info)
343 struct auth_user_info_dc *user_info_dc = NULL;
344 struct auth_session_info *session_info = NULL;
345 TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
348 nt_status = auth_anonymous_user_info_dc(mem_ctx,
349 lpcfg_netbios_name(lp_ctx),
351 if (!NT_STATUS_IS_OK(nt_status)) {
352 talloc_free(mem_ctx);
356 /* references the user_info_dc into the session_info */
357 nt_status = auth_generate_session_info(parent_ctx, NULL, NULL, user_info_dc, AUTH_SESSION_INFO_SIMPLE_PRIVILEGES, &session_info);
358 talloc_free(mem_ctx);
360 NT_STATUS_NOT_OK_RETURN(nt_status);
362 session_info->credentials = cli_credentials_init(session_info);
363 if (!session_info->credentials) {
364 return NT_STATUS_NO_MEMORY;
367 ok = cli_credentials_set_conf(session_info->credentials, lp_ctx);
369 return NT_STATUS_INTERNAL_ERROR;
371 cli_credentials_set_anonymous(session_info->credentials);
373 *_session_info = session_info;
378 _PUBLIC_ NTSTATUS auth_anonymous_user_info_dc(TALLOC_CTX *mem_ctx,
379 const char *netbios_name,
380 struct auth_user_info_dc **_user_info_dc)
382 struct auth_user_info_dc *user_info_dc;
383 struct auth_user_info *info;
384 user_info_dc = talloc_zero(mem_ctx, struct auth_user_info_dc);
385 NT_STATUS_HAVE_NO_MEMORY(user_info_dc);
387 /* This returns a pointer to a struct dom_sid, which is the
388 * same as a 1 element list of struct dom_sid */
389 user_info_dc->num_sids = 1;
390 user_info_dc->sids = talloc(user_info_dc, struct auth_SidAttr);
391 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->sids);
393 user_info_dc->sids->sid = global_sid_Anonymous;
394 user_info_dc->sids->attrs = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;
396 /* annoying, but the Anonymous really does have a session key... */
397 user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16);
398 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->user_session_key.data);
400 user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16);
401 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->lm_session_key.data);
403 /* and it is all zeros! */
404 data_blob_clear(&user_info_dc->user_session_key);
405 data_blob_clear(&user_info_dc->lm_session_key);
407 user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
408 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info);
410 info->account_name = talloc_strdup(info, "ANONYMOUS LOGON");
411 NT_STATUS_HAVE_NO_MEMORY(info->account_name);
413 info->domain_name = talloc_strdup(info, "NT AUTHORITY");
414 NT_STATUS_HAVE_NO_MEMORY(info->domain_name);
416 info->full_name = talloc_strdup(info, "Anonymous Logon");
417 NT_STATUS_HAVE_NO_MEMORY(info->full_name);
419 info->logon_script = talloc_strdup(info, "");
420 NT_STATUS_HAVE_NO_MEMORY(info->logon_script);
422 info->profile_path = talloc_strdup(info, "");
423 NT_STATUS_HAVE_NO_MEMORY(info->profile_path);
425 info->home_directory = talloc_strdup(info, "");
426 NT_STATUS_HAVE_NO_MEMORY(info->home_directory);
428 info->home_drive = talloc_strdup(info, "");
429 NT_STATUS_HAVE_NO_MEMORY(info->home_drive);
431 info->logon_server = talloc_strdup(info, netbios_name);
432 NT_STATUS_HAVE_NO_MEMORY(info->logon_server);
434 info->last_logon = 0;
435 info->last_logoff = 0;
436 info->acct_expiry = 0;
437 info->last_password_change = 0;
438 info->allow_password_change = 0;
439 info->force_password_change = 0;
441 info->logon_count = 0;
442 info->bad_password_count = 0;
444 info->acct_flags = ACB_NORMAL;
446 /* The user is not authenticated. */
447 info->user_flags = NETLOGON_GUEST;
449 *_user_info_dc = user_info_dc;