24
24
#include "includes.h"
25
25
#include "auth/auth.h"
26
#include "auth/auth_sam.h"
27
#include "auth/credentials/credentials.h"
28
#include "auth/credentials/credentials_krb5.h"
26
29
#include "libcli/security/security.h"
27
30
#include "libcli/auth/libcli_auth.h"
28
31
#include "dsdb/samdb/samdb.h"
29
#include "auth/credentials/credentials.h"
30
#include "param/param.h"
31
32
#include "auth/session_proto.h"
33
#include "system/kerberos.h"
34
#include <gssapi/gssapi.h>
33
36
_PUBLIC_ struct auth_session_info *anonymous_session(TALLOC_CTX *mem_ctx,
34
struct tevent_context *event_ctx,
35
struct loadparm_context *lp_ctx)
37
struct loadparm_context *lp_ctx)
37
39
NTSTATUS nt_status;
38
40
struct auth_session_info *session_info = NULL;
39
nt_status = auth_anonymous_session_info(mem_ctx, event_ctx, lp_ctx, &session_info);
41
nt_status = auth_anonymous_session_info(mem_ctx, lp_ctx, &session_info);
40
42
if (!NT_STATUS_IS_OK(nt_status)) {
43
45
return session_info;
46
_PUBLIC_ NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx,
47
struct tevent_context *event_ctx,
48
struct loadparm_context *lp_ctx,
49
struct auth_session_info **_session_info)
52
struct auth_serversupplied_info *server_info = NULL;
53
struct auth_session_info *session_info = NULL;
54
TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
56
nt_status = auth_anonymous_server_info(mem_ctx,
57
lp_netbios_name(lp_ctx),
59
if (!NT_STATUS_IS_OK(nt_status)) {
64
/* references the server_info into the session_info */
65
nt_status = auth_generate_session_info(parent_ctx, event_ctx, lp_ctx, server_info, &session_info);
68
NT_STATUS_NOT_OK_RETURN(nt_status);
70
session_info->credentials = cli_credentials_init(session_info);
71
if (!session_info->credentials) {
72
return NT_STATUS_NO_MEMORY;
75
cli_credentials_set_conf(session_info->credentials, lp_ctx);
76
cli_credentials_set_anonymous(session_info->credentials);
78
*_session_info = session_info;
83
_PUBLIC_ NTSTATUS auth_anonymous_server_info(TALLOC_CTX *mem_ctx,
84
const char *netbios_name,
85
struct auth_serversupplied_info **_server_info)
87
struct auth_serversupplied_info *server_info;
88
server_info = talloc(mem_ctx, struct auth_serversupplied_info);
89
NT_STATUS_HAVE_NO_MEMORY(server_info);
91
server_info->account_sid = dom_sid_parse_talloc(server_info, SID_NT_ANONYMOUS);
92
NT_STATUS_HAVE_NO_MEMORY(server_info->account_sid);
94
/* is this correct? */
95
server_info->primary_group_sid = dom_sid_parse_talloc(server_info, SID_BUILTIN_GUESTS);
96
NT_STATUS_HAVE_NO_MEMORY(server_info->primary_group_sid);
98
server_info->n_domain_groups = 0;
99
server_info->domain_groups = NULL;
101
/* annoying, but the Anonymous really does have a session key... */
102
server_info->user_session_key = data_blob_talloc(server_info, NULL, 16);
103
NT_STATUS_HAVE_NO_MEMORY(server_info->user_session_key.data);
105
server_info->lm_session_key = data_blob_talloc(server_info, NULL, 16);
106
NT_STATUS_HAVE_NO_MEMORY(server_info->lm_session_key.data);
108
/* and it is all zeros! */
109
data_blob_clear(&server_info->user_session_key);
110
data_blob_clear(&server_info->lm_session_key);
112
server_info->account_name = talloc_strdup(server_info, "ANONYMOUS LOGON");
113
NT_STATUS_HAVE_NO_MEMORY(server_info->account_name);
115
server_info->domain_name = talloc_strdup(server_info, "NT AUTHORITY");
116
NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name);
118
server_info->full_name = talloc_strdup(server_info, "Anonymous Logon");
119
NT_STATUS_HAVE_NO_MEMORY(server_info->full_name);
121
server_info->logon_script = talloc_strdup(server_info, "");
122
NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script);
124
server_info->profile_path = talloc_strdup(server_info, "");
125
NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path);
127
server_info->home_directory = talloc_strdup(server_info, "");
128
NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory);
130
server_info->home_drive = talloc_strdup(server_info, "");
131
NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive);
133
server_info->logon_server = talloc_strdup(server_info, netbios_name);
134
NT_STATUS_HAVE_NO_MEMORY(server_info->logon_server);
136
server_info->last_logon = 0;
137
server_info->last_logoff = 0;
138
server_info->acct_expiry = 0;
139
server_info->last_password_change = 0;
140
server_info->allow_password_change = 0;
141
server_info->force_password_change = 0;
143
server_info->logon_count = 0;
144
server_info->bad_password_count = 0;
146
server_info->acct_flags = ACB_NORMAL;
148
server_info->authenticated = false;
150
*_server_info = server_info;
155
_PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
156
struct tevent_context *event_ctx,
157
struct loadparm_context *lp_ctx,
158
struct auth_serversupplied_info *server_info,
159
struct auth_session_info **_session_info)
48
_PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
49
struct loadparm_context *lp_ctx, /* Optional, if you don't want privilages */
50
struct ldb_context *sam_ctx, /* Optional, if you don't want local groups */
51
struct auth_user_info_dc *user_info_dc,
52
uint32_t session_info_flags,
53
struct auth_session_info **_session_info)
161
55
struct auth_session_info *session_info;
162
56
NTSTATUS nt_status;
164
session_info = talloc(mem_ctx, struct auth_session_info);
165
NT_STATUS_HAVE_NO_MEMORY(session_info);
167
session_info->server_info = talloc_reference(session_info, server_info);
57
unsigned int i, num_sids = 0;
61
struct dom_sid *sids = NULL;
62
const struct dom_sid *anonymous_sid, *system_sid;
64
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
65
NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
67
session_info = talloc(tmp_ctx, struct auth_session_info);
68
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info, tmp_ctx);
70
session_info->info = talloc_reference(session_info, user_info_dc->info);
72
session_info->torture = talloc_zero(session_info, struct auth_user_info_torture);
73
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info->torture, tmp_ctx);
74
session_info->torture->num_dc_sids = user_info_dc->num_sids;
75
session_info->torture->dc_sids = talloc_reference(session_info, user_info_dc->sids);
76
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info->torture->dc_sids, tmp_ctx);
169
78
/* unless set otherwise, the session key is the user session
170
79
* key from the auth subsystem */
171
session_info->session_key = server_info->user_session_key;
80
session_info->session_key = data_blob_talloc(session_info, user_info_dc->user_session_key.data, user_info_dc->user_session_key.length);
81
if (!session_info->session_key.data && session_info->session_key.length) {
82
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info->session_key.data, tmp_ctx);
85
anonymous_sid = dom_sid_parse_talloc(tmp_ctx, SID_NT_ANONYMOUS);
86
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(anonymous_sid, tmp_ctx);
88
system_sid = dom_sid_parse_talloc(tmp_ctx, SID_NT_SYSTEM);
89
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(system_sid, tmp_ctx);
91
sids = talloc_array(tmp_ctx, struct dom_sid, user_info_dc->num_sids);
92
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sids, tmp_ctx);
95
return NT_STATUS_NO_MEMORY;
98
num_sids = user_info_dc->num_sids;
100
for (i=0; i < user_info_dc->num_sids; i++) {
101
sids[i] = user_info_dc->sids[i];
104
if (user_info_dc->num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(anonymous_sid, &user_info_dc->sids[PRIMARY_USER_SID_INDEX])) {
105
/* Don't expand nested groups of system, anonymous etc*/
106
} else if (user_info_dc->num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(system_sid, &user_info_dc->sids[PRIMARY_USER_SID_INDEX])) {
107
/* Don't expand nested groups of system, anonymous etc*/
108
} else if (sam_ctx) {
109
filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
110
GROUP_TYPE_BUILTIN_LOCAL_GROUP);
112
/* Search for each group in the token */
113
for (i = 0; i < user_info_dc->num_sids; i++) {
118
sid_string = dom_sid_string(tmp_ctx,
119
&user_info_dc->sids[i]);
120
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, user_info_dc);
122
sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
123
talloc_free(sid_string);
124
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, user_info_dc);
125
sid_blob = data_blob_string_const(sid_dn);
127
/* This function takes in memberOf values and expands
128
* them, as long as they meet the filter - so only
131
* We already have the SID in the token, so set
132
* 'only childs' flag to true */
133
nt_status = dsdb_expand_nested_groups(sam_ctx, &sid_blob, true, filter,
134
tmp_ctx, &sids, &num_sids);
135
if (!NT_STATUS_IS_OK(nt_status)) {
136
talloc_free(tmp_ctx);
173
142
nt_status = security_token_create(session_info,
176
server_info->account_sid,
177
server_info->primary_group_sid,
178
server_info->n_domain_groups,
179
server_info->domain_groups,
180
server_info->authenticated,
181
147
&session_info->security_token);
182
NT_STATUS_NOT_OK_RETURN(nt_status);
148
NT_STATUS_NOT_OK_RETURN_AND_FREE(nt_status, tmp_ctx);
184
150
session_info->credentials = NULL;
152
talloc_steal(mem_ctx, session_info);
186
153
*_session_info = session_info;
154
talloc_free(tmp_ctx);
158
/* Create a session_info structure from the
159
* auth_session_info_transport we were forwarded over named pipe
162
* NOTE: The stucture members of session_info_transport are stolen
163
* with talloc_move() into auth_session_info for long term use
165
struct auth_session_info *auth_session_info_from_transport(TALLOC_CTX *mem_ctx,
166
struct auth_session_info_transport *session_info_transport,
167
struct loadparm_context *lp_ctx,
170
struct auth_session_info *session_info;
171
session_info = talloc_zero(mem_ctx, struct auth_session_info);
173
*reason = "failed to allocate session_info";
177
session_info->security_token = talloc_move(session_info, &session_info_transport->security_token);
178
session_info->info = talloc_move(session_info, &session_info_transport->info);
179
session_info->session_key = session_info_transport->session_key;
180
session_info->session_key.data = talloc_move(session_info, &session_info_transport->session_key.data);
182
if (session_info_transport->exported_gssapi_credentials.length) {
183
struct cli_credentials *creds;
184
OM_uint32 minor_status;
185
gss_buffer_desc cred_token;
186
gss_cred_id_t cred_handle;
187
const char *error_string;
190
DEBUG(10, ("Delegated credentials supplied by client\n"));
192
cred_token.value = session_info_transport->exported_gssapi_credentials.data;
193
cred_token.length = session_info_transport->exported_gssapi_credentials.length;
195
ret = gss_import_cred(&minor_status,
198
if (ret != GSS_S_COMPLETE) {
199
*reason = "Internal error in gss_import_cred()";
203
creds = cli_credentials_init(session_info);
205
*reason = "Out of memory in cli_credentials_init()";
208
session_info->credentials = creds;
210
cli_credentials_set_conf(creds, lp_ctx);
211
/* Just so we don't segfault trying to get at a username */
212
cli_credentials_set_anonymous(creds);
214
ret = cli_credentials_set_client_gss_creds(creds,
220
*reason = talloc_asprintf(mem_ctx,
221
"Failed to set pipe forwarded"
222
"creds: %s\n", error_string);
226
/* This credential handle isn't useful for password
227
* authentication, so ensure nobody tries to do that */
228
cli_credentials_set_kerberos_state(creds,
229
CRED_MUST_USE_KERBEROS);
237
/* Create a auth_session_info_transport from an auth_session_info.
239
* NOTE: Members of the auth_session_info_transport structure are not talloc_referenced, but simply assigned. They are only valid for the lifetime of the struct auth_session_info
241
* This isn't normally an issue, as the auth_session_info has a very long typical life
243
NTSTATUS auth_session_info_transport_from_session(TALLOC_CTX *mem_ctx,
244
struct auth_session_info *session_info,
245
struct tevent_context *event_ctx,
246
struct loadparm_context *lp_ctx,
247
struct auth_session_info_transport **transport_out)
250
struct auth_session_info_transport *session_info_transport = talloc_zero(mem_ctx, struct auth_session_info_transport);
251
session_info_transport->security_token = talloc_reference(session_info, session_info->security_token);
252
NT_STATUS_HAVE_NO_MEMORY(session_info_transport->security_token);
254
session_info_transport->info = talloc_reference(session_info, session_info->info);
255
NT_STATUS_HAVE_NO_MEMORY(session_info_transport->info);
257
session_info_transport->session_key = session_info->session_key;
258
session_info_transport->session_key.data = talloc_reference(session_info, session_info->session_key.data);
259
if (!session_info_transport->session_key.data && session_info->session_key.length) {
260
return NT_STATUS_NO_MEMORY;
263
if (session_info->credentials) {
264
struct gssapi_creds_container *gcc;
266
OM_uint32 minor_status;
267
gss_buffer_desc cred_token;
268
const char *error_string;
271
ret = cli_credentials_get_client_gss_creds(session_info->credentials,
274
&gcc, &error_string);
276
*transport_out = session_info_transport;
280
gret = gss_export_cred(&minor_status,
283
if (gret != GSS_S_COMPLETE) {
284
return NT_STATUS_INTERNAL_ERROR;
287
if (cred_token.length) {
288
session_info_transport->exported_gssapi_credentials
289
= data_blob_talloc(session_info_transport,
292
gss_release_buffer(&minor_status, &cred_token);
293
NT_STATUS_HAVE_NO_MEMORY(session_info_transport->exported_gssapi_credentials.data);
296
*transport_out = session_info_transport;
301
/* Produce a session_info for an arbitary DN or principal in the local
302
* DB, assuming the local DB holds all the groups
304
* Supply either a principal or a DN
306
NTSTATUS authsam_get_session_info_principal(TALLOC_CTX *mem_ctx,
307
struct loadparm_context *lp_ctx,
308
struct ldb_context *sam_ctx,
309
const char *principal,
310
struct ldb_dn *user_dn,
311
uint32_t session_info_flags,
312
struct auth_session_info **session_info)
315
struct auth_user_info_dc *user_info_dc;
316
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
318
return NT_STATUS_NO_MEMORY;
320
nt_status = authsam_get_user_info_dc_principal(tmp_ctx, lp_ctx, sam_ctx,
323
if (!NT_STATUS_IS_OK(nt_status)) {
324
talloc_free(tmp_ctx);
328
nt_status = auth_generate_session_info(tmp_ctx, lp_ctx, sam_ctx,
329
user_info_dc, session_info_flags,
332
if (NT_STATUS_IS_OK(nt_status)) {
333
talloc_steal(mem_ctx, *session_info);
335
talloc_free(tmp_ctx);