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_DEFAULT_FLAGS
;
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
= 8;
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
= SE_GROUP_DEFAULT_FLAGS
;
211 user_info_dc
->sids
[PRIMARY_GROUP_SID_INDEX
].sid
= *domain_sid
;
212 sid_append_rid(&user_info_dc
->sids
[PRIMARY_GROUP_SID_INDEX
].sid
, DOMAIN_RID_USERS
);
213 user_info_dc
->sids
[PRIMARY_GROUP_SID_INDEX
].attrs
= SE_GROUP_DEFAULT_FLAGS
;
215 /* Add the primary group again. */
216 user_info_dc
->sids
[2] = user_info_dc
->sids
[PRIMARY_GROUP_SID_INDEX
];
218 user_info_dc
->sids
[3].sid
= global_sid_Builtin_Administrators
;
219 user_info_dc
->sids
[3].attrs
= SE_GROUP_DEFAULT_FLAGS
;
221 user_info_dc
->sids
[4].sid
= *domain_sid
;
222 sid_append_rid(&user_info_dc
->sids
[4].sid
, DOMAIN_RID_ADMINS
);
223 user_info_dc
->sids
[4].attrs
= SE_GROUP_DEFAULT_FLAGS
;
224 user_info_dc
->sids
[5].sid
= *domain_sid
;
225 sid_append_rid(&user_info_dc
->sids
[5].sid
, DOMAIN_RID_ENTERPRISE_ADMINS
);
226 user_info_dc
->sids
[5].attrs
= SE_GROUP_DEFAULT_FLAGS
;
227 user_info_dc
->sids
[6].sid
= *domain_sid
;
228 sid_append_rid(&user_info_dc
->sids
[6].sid
, DOMAIN_RID_POLICY_ADMINS
);
229 user_info_dc
->sids
[6].attrs
= SE_GROUP_DEFAULT_FLAGS
;
230 user_info_dc
->sids
[7].sid
= *domain_sid
;
231 sid_append_rid(&user_info_dc
->sids
[7].sid
, DOMAIN_RID_SCHEMA_ADMINS
);
232 user_info_dc
->sids
[7].attrs
= SE_GROUP_DEFAULT_FLAGS
;
234 /* What should the session key be?*/
235 user_info_dc
->user_session_key
= data_blob_talloc(user_info_dc
, NULL
, 16);
236 NT_STATUS_HAVE_NO_MEMORY(user_info_dc
->user_session_key
.data
);
238 user_info_dc
->lm_session_key
= data_blob_talloc(user_info_dc
, NULL
, 16);
239 NT_STATUS_HAVE_NO_MEMORY(user_info_dc
->lm_session_key
.data
);
241 data_blob_clear(&user_info_dc
->user_session_key
);
242 data_blob_clear(&user_info_dc
->lm_session_key
);
244 user_info_dc
->info
= info
= talloc_zero(user_info_dc
, struct auth_user_info
);
245 NT_STATUS_HAVE_NO_MEMORY(user_info_dc
->info
);
247 info
->account_name
= talloc_strdup(info
, "Administrator");
248 NT_STATUS_HAVE_NO_MEMORY(info
->account_name
);
250 info
->domain_name
= talloc_strdup(info
, domain_name
);
251 NT_STATUS_HAVE_NO_MEMORY(info
->domain_name
);
253 info
->full_name
= talloc_strdup(info
, "Administrator");
254 NT_STATUS_HAVE_NO_MEMORY(info
->full_name
);
256 info
->logon_script
= talloc_strdup(info
, "");
257 NT_STATUS_HAVE_NO_MEMORY(info
->logon_script
);
259 info
->profile_path
= talloc_strdup(info
, "");
260 NT_STATUS_HAVE_NO_MEMORY(info
->profile_path
);
262 info
->home_directory
= talloc_strdup(info
, "");
263 NT_STATUS_HAVE_NO_MEMORY(info
->home_directory
);
265 info
->home_drive
= talloc_strdup(info
, "");
266 NT_STATUS_HAVE_NO_MEMORY(info
->home_drive
);
268 info
->logon_server
= talloc_strdup(info
, netbios_name
);
269 NT_STATUS_HAVE_NO_MEMORY(info
->logon_server
);
271 info
->last_logon
= 0;
272 info
->last_logoff
= 0;
273 info
->acct_expiry
= 0;
274 info
->last_password_change
= 0;
275 info
->allow_password_change
= 0;
276 info
->force_password_change
= 0;
278 info
->logon_count
= 0;
279 info
->bad_password_count
= 0;
281 info
->acct_flags
= ACB_NORMAL
;
283 info
->user_flags
= 0;
285 *_user_info_dc
= user_info_dc
;
290 static NTSTATUS
auth_domain_admin_session_info(TALLOC_CTX
*parent_ctx
,
291 struct loadparm_context
*lp_ctx
,
292 struct dom_sid
*domain_sid
,
293 struct auth_session_info
**session_info
)
296 struct auth_user_info_dc
*user_info_dc
= NULL
;
297 TALLOC_CTX
*mem_ctx
= talloc_new(parent_ctx
);
299 NT_STATUS_HAVE_NO_MEMORY(mem_ctx
);
301 nt_status
= auth_domain_admin_user_info_dc(mem_ctx
, lpcfg_netbios_name(lp_ctx
),
302 lpcfg_workgroup(lp_ctx
), domain_sid
,
304 if (!NT_STATUS_IS_OK(nt_status
)) {
305 talloc_free(mem_ctx
);
309 nt_status
= auth_generate_session_info(mem_ctx
, NULL
, NULL
, user_info_dc
,
310 AUTH_SESSION_INFO_SIMPLE_PRIVILEGES
|AUTH_SESSION_INFO_AUTHENTICATED
|AUTH_SESSION_INFO_DEFAULT_GROUPS
,
312 /* There is already a reference between the session_info and user_info_dc */
313 if (NT_STATUS_IS_OK(nt_status
)) {
314 talloc_steal(parent_ctx
, *session_info
);
316 talloc_free(mem_ctx
);
320 _PUBLIC_
struct auth_session_info
*admin_session(TALLOC_CTX
*mem_ctx
, struct loadparm_context
*lp_ctx
, struct dom_sid
*domain_sid
)
323 struct auth_session_info
*session_info
= NULL
;
324 nt_status
= auth_domain_admin_session_info(mem_ctx
,
328 if (!NT_STATUS_IS_OK(nt_status
)) {
334 _PUBLIC_ NTSTATUS
auth_anonymous_session_info(TALLOC_CTX
*parent_ctx
,
335 struct loadparm_context
*lp_ctx
,
336 struct auth_session_info
**_session_info
)
339 struct auth_user_info_dc
*user_info_dc
= NULL
;
340 struct auth_session_info
*session_info
= NULL
;
341 TALLOC_CTX
*mem_ctx
= talloc_new(parent_ctx
);
344 nt_status
= auth_anonymous_user_info_dc(mem_ctx
,
345 lpcfg_netbios_name(lp_ctx
),
347 if (!NT_STATUS_IS_OK(nt_status
)) {
348 talloc_free(mem_ctx
);
352 /* references the user_info_dc into the session_info */
353 nt_status
= auth_generate_session_info(parent_ctx
, NULL
, NULL
, user_info_dc
, AUTH_SESSION_INFO_SIMPLE_PRIVILEGES
, &session_info
);
354 talloc_free(mem_ctx
);
356 NT_STATUS_NOT_OK_RETURN(nt_status
);
358 session_info
->credentials
= cli_credentials_init(session_info
);
359 if (!session_info
->credentials
) {
360 return NT_STATUS_NO_MEMORY
;
363 ok
= cli_credentials_set_conf(session_info
->credentials
, lp_ctx
);
365 return NT_STATUS_INTERNAL_ERROR
;
367 cli_credentials_set_anonymous(session_info
->credentials
);
369 *_session_info
= session_info
;
374 _PUBLIC_ NTSTATUS
auth_anonymous_user_info_dc(TALLOC_CTX
*mem_ctx
,
375 const char *netbios_name
,
376 struct auth_user_info_dc
**_user_info_dc
)
378 struct auth_user_info_dc
*user_info_dc
;
379 struct auth_user_info
*info
;
380 user_info_dc
= talloc_zero(mem_ctx
, struct auth_user_info_dc
);
381 NT_STATUS_HAVE_NO_MEMORY(user_info_dc
);
383 /* This returns a pointer to a struct dom_sid, which is the
384 * same as a 1 element list of struct dom_sid */
385 user_info_dc
->num_sids
= 1;
386 user_info_dc
->sids
= talloc(user_info_dc
, struct auth_SidAttr
);
387 NT_STATUS_HAVE_NO_MEMORY(user_info_dc
->sids
);
389 user_info_dc
->sids
->sid
= global_sid_Anonymous
;
390 user_info_dc
->sids
->attrs
= SE_GROUP_DEFAULT_FLAGS
;
392 /* annoying, but the Anonymous really does have a session key... */
393 user_info_dc
->user_session_key
= data_blob_talloc(user_info_dc
, NULL
, 16);
394 NT_STATUS_HAVE_NO_MEMORY(user_info_dc
->user_session_key
.data
);
396 user_info_dc
->lm_session_key
= data_blob_talloc(user_info_dc
, NULL
, 16);
397 NT_STATUS_HAVE_NO_MEMORY(user_info_dc
->lm_session_key
.data
);
399 /* and it is all zeros! */
400 data_blob_clear(&user_info_dc
->user_session_key
);
401 data_blob_clear(&user_info_dc
->lm_session_key
);
403 user_info_dc
->info
= info
= talloc_zero(user_info_dc
, struct auth_user_info
);
404 NT_STATUS_HAVE_NO_MEMORY(user_info_dc
->info
);
406 info
->account_name
= talloc_strdup(info
, "ANONYMOUS LOGON");
407 NT_STATUS_HAVE_NO_MEMORY(info
->account_name
);
409 info
->domain_name
= talloc_strdup(info
, "NT AUTHORITY");
410 NT_STATUS_HAVE_NO_MEMORY(info
->domain_name
);
412 info
->full_name
= talloc_strdup(info
, "Anonymous Logon");
413 NT_STATUS_HAVE_NO_MEMORY(info
->full_name
);
415 info
->logon_script
= talloc_strdup(info
, "");
416 NT_STATUS_HAVE_NO_MEMORY(info
->logon_script
);
418 info
->profile_path
= talloc_strdup(info
, "");
419 NT_STATUS_HAVE_NO_MEMORY(info
->profile_path
);
421 info
->home_directory
= talloc_strdup(info
, "");
422 NT_STATUS_HAVE_NO_MEMORY(info
->home_directory
);
424 info
->home_drive
= talloc_strdup(info
, "");
425 NT_STATUS_HAVE_NO_MEMORY(info
->home_drive
);
427 info
->logon_server
= talloc_strdup(info
, netbios_name
);
428 NT_STATUS_HAVE_NO_MEMORY(info
->logon_server
);
430 info
->last_logon
= 0;
431 info
->last_logoff
= 0;
432 info
->acct_expiry
= 0;
433 info
->last_password_change
= 0;
434 info
->allow_password_change
= 0;
435 info
->force_password_change
= 0;
437 info
->logon_count
= 0;
438 info
->bad_password_count
= 0;
440 info
->acct_flags
= ACB_NORMAL
;
442 /* The user is not authenticated. */
443 info
->user_flags
= NETLOGON_GUEST
;
445 *_user_info_dc
= user_info_dc
;