diff options
-rw-r--r-- | source4/auth/auth.h | 5 | ||||
-rw-r--r-- | source4/auth/gensec/gensec.c | 8 | ||||
-rw-r--r-- | source4/auth/ntlm/auth_simple.c | 8 | ||||
-rw-r--r-- | source4/auth/session.c | 7 | ||||
-rw-r--r-- | source4/auth/session.h | 1 | ||||
-rw-r--r-- | source4/auth/system_session.c | 12 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/operational.c | 20 | ||||
-rw-r--r-- | source4/dsdb/samdb/samdb.c | 61 | ||||
-rw-r--r-- | source4/smb_server/smb/sesssetup.c | 14 | ||||
-rw-r--r-- | source4/smbd/service_named_pipe.c | 41 |
10 files changed, 139 insertions, 38 deletions
diff --git a/source4/auth/auth.h b/source4/auth/auth.h index 0e32c504dd..9ce338c8ae 100644 --- a/source4/auth/auth.h +++ b/source4/auth/auth.h @@ -48,6 +48,10 @@ struct loadparm_context; #define USER_INFO_DONT_CHECK_UNIX_ACCOUNT 0x04 /* don't check unix account status */ #define USER_INFO_INTERACTIVE_LOGON 0x08 /* don't check unix account status */ +#define AUTH_SESSION_INFO_DEFAULT_GROUPS 0x01 /* Add the user to the default world and network groups */ +#define AUTH_SESSION_INFO_AUTHENTICATED 0x02 /* Add the user to the 'authenticated users' group */ +#define AUTH_SESSION_INFO_ENTERPRISE_DC 0x04 /* Add the user to the 'enterprise DC' group */ + enum auth_password_state { AUTH_PASSWORD_RESPONSE, AUTH_PASSWORD_HASH, @@ -211,6 +215,7 @@ struct auth_context { NTSTATUS (*generate_session_info)(TALLOC_CTX *mem_ctx, struct auth_context *auth_context, struct auth_serversupplied_info *server_info, + uint32_t session_info_flags, struct auth_session_info **session_info); }; diff --git a/source4/auth/gensec/gensec.c b/source4/auth/gensec/gensec.c index c19d5ff5d5..b166d238de 100644 --- a/source4/auth/gensec/gensec.c +++ b/source4/auth/gensec/gensec.c @@ -1327,8 +1327,14 @@ NTSTATUS gensec_generate_session_info(TALLOC_CTX *mem_ctx, { NTSTATUS nt_status; if (gensec_security->auth_context) { + uint32_t flags = AUTH_SESSION_INFO_DEFAULT_GROUPS; + if (server_info->authenticated) { + flags |= AUTH_SESSION_INFO_AUTHENTICATED; + } nt_status = gensec_security->auth_context->generate_session_info(mem_ctx, gensec_security->auth_context, - server_info, session_info); + server_info, + flags, + session_info); } else { nt_status = auth_generate_simple_session_info(mem_ctx, server_info, session_info); diff --git a/source4/auth/ntlm/auth_simple.c b/source4/auth/ntlm/auth_simple.c index 7f972ac296..9c8f7f64ac 100644 --- a/source4/auth/ntlm/auth_simple.c +++ b/source4/auth/ntlm/auth_simple.c @@ -87,8 +87,14 @@ _PUBLIC_ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx, } if (session_info) { + uint32_t flags = AUTH_SESSION_INFO_DEFAULT_GROUPS; + if (server_info->authenticated) { + flags |= AUTH_SESSION_INFO_AUTHENTICATED; + } nt_status = auth_context->generate_session_info(tmp_ctx, auth_context, - server_info, session_info); + server_info, + flags, + session_info); if (NT_STATUS_IS_OK(nt_status)) { talloc_steal(mem_ctx, *session_info); diff --git a/source4/auth/session.c b/source4/auth/session.c index 7817195727..a21fbcf451 100644 --- a/source4/auth/session.c +++ b/source4/auth/session.c @@ -45,6 +45,7 @@ _PUBLIC_ struct auth_session_info *anonymous_session(TALLOC_CTX *mem_ctx, _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx, struct auth_context *auth_context, struct auth_serversupplied_info *server_info, + uint32_t session_info_flags, struct auth_session_info **_session_info) { struct auth_session_info *session_info; @@ -61,7 +62,6 @@ _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx, struct dom_sid **groupSIDs = NULL; const struct dom_sid *dom_sid; - bool is_enterprise_dc = false; TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); @@ -82,7 +82,7 @@ _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx, dom_sid = samdb_domain_sid(auth_context->sam_ctx); if (dom_sid) { if (dom_sid_in_domain(dom_sid, server_info->account_sid)) { - is_enterprise_dc = true; + session_info_flags |= AUTH_SESSION_INFO_ENTERPRISE_DC; } else { DEBUG(2, ("DC %s is not in our domain. " "It will not have Enterprise Domain Controllers membership on this server", @@ -201,8 +201,7 @@ _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx, server_info->primary_group_sid, num_groupSIDs, groupSIDs, - server_info->authenticated, - is_enterprise_dc, + session_info_flags, &session_info->security_token); NT_STATUS_NOT_OK_RETURN_AND_FREE(nt_status, tmp_ctx); diff --git a/source4/auth/session.h b/source4/auth/session.h index 574b76946e..8e22cc0576 100644 --- a/source4/auth/session.h +++ b/source4/auth/session.h @@ -50,6 +50,7 @@ NTSTATUS auth_anonymous_server_info(TALLOC_CTX *mem_ctx, NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx, struct auth_context *auth_context, struct auth_serversupplied_info *server_info, + uint32_t session_info_flags, struct auth_session_info **_session_info); NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx, diff --git a/source4/auth/system_session.c b/source4/auth/system_session.c index c6df082f69..2835a20e34 100644 --- a/source4/auth/system_session.c +++ b/source4/auth/system_session.c @@ -36,12 +36,12 @@ * @note Specialised version for system sessions that doesn't use the SAM. */ static NTSTATUS create_token(TALLOC_CTX *mem_ctx, - struct dom_sid *user_sid, - struct dom_sid *group_sid, - unsigned int n_groupSIDs, - struct dom_sid **groupSIDs, - bool is_authenticated, - struct security_token **token) + struct dom_sid *user_sid, + struct dom_sid *group_sid, + unsigned int n_groupSIDs, + struct dom_sid **groupSIDs, + bool is_authenticated, + struct security_token **token) { struct security_token *ptoken; unsigned int i; diff --git a/source4/dsdb/samdb/ldb_modules/operational.c b/source4/dsdb/samdb/ldb_modules/operational.c index acd8b80161..d51a8588bb 100644 --- a/source4/dsdb/samdb/ldb_modules/operational.c +++ b/source4/dsdb/samdb/ldb_modules/operational.c @@ -149,6 +149,7 @@ static int construct_token_groups(struct ldb_module *module, ldb_module_oom(module); return LDB_ERR_OPERATIONS_ERROR; } else if (!NT_STATUS_IS_OK(status)) { + ldb_set_errstring(ldb, "Cannot provide tokenGroups attribute, could not create authContext"); talloc_free(tmp_ctx); return LDB_ERR_OPERATIONS_ERROR; } @@ -158,30 +159,29 @@ static int construct_token_groups(struct ldb_module *module, talloc_free(tmp_ctx); ldb_module_oom(module); return LDB_ERR_OPERATIONS_ERROR; + } else if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) { + /* Not a user, we have no tokenGroups */ + talloc_free(tmp_ctx); + return LDB_SUCCESS; } else if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); + ldb_asprintf_errstring(ldb, "Cannot provide tokenGroups attribute: auth_get_server_info_principal failed: %s", nt_errstr(status)); return LDB_ERR_OPERATIONS_ERROR; } - status = auth_generate_session_info(tmp_ctx, auth_context, server_info, &session_info); + status = auth_generate_session_info(tmp_ctx, auth_context, server_info, 0, &session_info); if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MEMORY)) { talloc_free(tmp_ctx); ldb_module_oom(module); return LDB_ERR_OPERATIONS_ERROR; } else if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); + ldb_asprintf_errstring(ldb, "Cannot provide tokenGroups attribute: auth_generate_session_info failed: %s", nt_errstr(status)); return LDB_ERR_OPERATIONS_ERROR; } - ret = samdb_msg_add_dom_sid(ldb, msg, msg, - "tokenGroups", - session_info->security_token->group_sid); - if (ret != LDB_SUCCESS) { - talloc_free(tmp_ctx); - return ret; - } - - for (i = 0; i < session_info->security_token->num_sids; i++) { + /* We start at 1, as the first SID is the user's SID, not included in the tokenGroups */ + for (i = 1; i < session_info->security_token->num_sids; i++) { ret = samdb_msg_add_dom_sid(ldb, msg, msg, "tokenGroups", session_info->security_token->sids[i]); diff --git a/source4/dsdb/samdb/samdb.c b/source4/dsdb/samdb/samdb.c index 9e4156407e..67b55385cb 100644 --- a/source4/dsdb/samdb/samdb.c +++ b/source4/dsdb/samdb/samdb.c @@ -41,6 +41,7 @@ #include "lib/events/events.h" #include "auth/credentials/credentials.h" #include "param/secrets.h" +#include "auth/auth.h" char *samdb_relative_path(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, @@ -146,8 +147,7 @@ NTSTATUS security_token_create(TALLOC_CTX *mem_ctx, struct dom_sid *group_sid, unsigned int n_groupSIDs, struct dom_sid **groupSIDs, - bool is_authenticated, - bool is_dc, + uint32_t session_info_flags, struct security_token **token) { struct security_token *ptoken; @@ -157,36 +157,61 @@ NTSTATUS security_token_create(TALLOC_CTX *mem_ctx, ptoken = security_token_initialise(mem_ctx); NT_STATUS_HAVE_NO_MEMORY(ptoken); - ptoken->sids = talloc_array(ptoken, struct dom_sid *, n_groupSIDs + 6); - NT_STATUS_HAVE_NO_MEMORY(ptoken->sids); - ptoken->user_sid = talloc_reference(ptoken, user_sid); ptoken->group_sid = talloc_reference(ptoken, group_sid); ptoken->privilege_mask = 0; + ptoken->sids = talloc_array(ptoken, struct dom_sid *, n_groupSIDs + 6 /* over-allocate */); + NT_STATUS_HAVE_NO_MEMORY(ptoken->sids); + + ptoken->num_sids = 1; + + ptoken->sids = talloc_realloc(ptoken, ptoken->sids, struct dom_sid *, ptoken->num_sids + 1); + NT_STATUS_HAVE_NO_MEMORY(ptoken->sids); + ptoken->sids[0] = ptoken->user_sid; ptoken->sids[1] = ptoken->group_sid; + ptoken->num_sids++; /* * Finally add the "standard" SIDs. * The only difference between guest and "anonymous" * is the addition of Authenticated_Users. */ - ptoken->sids[2] = dom_sid_parse_talloc(ptoken->sids, SID_WORLD); - NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[2]); - ptoken->sids[3] = dom_sid_parse_talloc(ptoken->sids, SID_NT_NETWORK); - NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[3]); - ptoken->num_sids = 4; - if (is_authenticated) { + if (session_info_flags & AUTH_SESSION_INFO_DEFAULT_GROUPS) { + ptoken->sids = talloc_realloc(ptoken, ptoken->sids, struct dom_sid *, ptoken->num_sids + 1); + NT_STATUS_HAVE_NO_MEMORY(ptoken->sids); + + ptoken->sids[ptoken->num_sids] = dom_sid_parse_talloc(ptoken->sids, SID_WORLD); + NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[ptoken->num_sids]); + ptoken->num_sids++; + + ptoken->sids = talloc_realloc(ptoken, ptoken->sids, struct dom_sid *, ptoken->num_sids + 1); + NT_STATUS_HAVE_NO_MEMORY(ptoken->sids); + + ptoken->sids[ptoken->num_sids] = dom_sid_parse_talloc(ptoken->sids, SID_NT_NETWORK); + NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[ptoken->num_sids]); + ptoken->num_sids++; + + + } + + if (session_info_flags & AUTH_SESSION_INFO_AUTHENTICATED) { + ptoken->sids = talloc_realloc(ptoken, ptoken->sids, struct dom_sid *, ptoken->num_sids + 1); + NT_STATUS_HAVE_NO_MEMORY(ptoken->sids); + ptoken->sids[ptoken->num_sids] = dom_sid_parse_talloc(ptoken->sids, SID_NT_AUTHENTICATED_USERS); - NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[4]); + NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[ptoken->num_sids]); ptoken->num_sids++; } - if (is_dc) { + if (session_info_flags & AUTH_SESSION_INFO_ENTERPRISE_DC) { + ptoken->sids = talloc_realloc(ptoken, ptoken->sids, struct dom_sid *, ptoken->num_sids + 1); + NT_STATUS_HAVE_NO_MEMORY(ptoken->sids); + ptoken->sids[ptoken->num_sids] = dom_sid_parse_talloc(ptoken->sids, SID_NT_ENTERPRISE_DCS); - NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[4]); + NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[ptoken->num_sids]); ptoken->num_sids++; } @@ -201,7 +226,13 @@ NTSTATUS security_token_create(TALLOC_CTX *mem_ctx, } if (check_sid_idx == ptoken->num_sids) { - ptoken->sids[ptoken->num_sids++] = talloc_reference(ptoken->sids, groupSIDs[i]); + ptoken->sids = talloc_realloc(ptoken, ptoken->sids, struct dom_sid *, ptoken->num_sids + 1); + NT_STATUS_HAVE_NO_MEMORY(ptoken->sids); + + ptoken->sids[ptoken->num_sids] = talloc_reference(ptoken->sids, groupSIDs[i]); + NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[ptoken->num_sids]); + ptoken->num_sids++; + } } diff --git a/source4/smb_server/smb/sesssetup.c b/source4/smb_server/smb/sesssetup.c index afc33dd3c6..b61fce0887 100644 --- a/source4/smb_server/smb/sesssetup.c +++ b/source4/smb_server/smb/sesssetup.c @@ -71,15 +71,20 @@ static void sesssetup_old_send(struct tevent_req *subreq) struct auth_session_info *session_info; struct smbsrv_session *smb_sess; NTSTATUS status; + uint32_t flags; status = auth_check_password_recv(subreq, req, &server_info); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) goto failed; + flags = AUTH_SESSION_INFO_DEFAULT_GROUPS; + if (server_info->authenticated) { + flags |= AUTH_SESSION_INFO_AUTHENTICATED; + } /* This references server_info into session_info */ status = req->smb_conn->negotiate.auth_context->generate_session_info(req, req->smb_conn->negotiate.auth_context, - server_info, &session_info); + server_info, flags, &session_info); if (!NT_STATUS_IS_OK(status)) goto failed; /* allocate a new session */ @@ -196,16 +201,23 @@ static void sesssetup_nt1_send(struct tevent_req *subreq) struct auth_session_info *session_info; struct smbsrv_session *smb_sess; + uint32_t flags; NTSTATUS status; status = auth_check_password_recv(subreq, req, &server_info); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) goto failed; + flags = AUTH_SESSION_INFO_DEFAULT_GROUPS; + if (server_info->authenticated) { + flags |= AUTH_SESSION_INFO_AUTHENTICATED; + } + /* This references server_info into session_info */ status = state->auth_context->generate_session_info(req, state->auth_context, server_info, + flags, &session_info); if (!NT_STATUS_IS_OK(status)) goto failed; diff --git a/source4/smbd/service_named_pipe.c b/source4/smbd/service_named_pipe.c index d78fd72cc2..235d4c2a3a 100644 --- a/source4/smbd/service_named_pipe.c +++ b/source4/smbd/service_named_pipe.c @@ -35,6 +35,7 @@ #include "libcli/raw/smb.h" #include "auth/credentials/credentials.h" #include "auth/credentials/credentials_krb5.h" +#include "libcli/security/dom_sid.h" struct named_pipe_socket { const char *pipe_name; @@ -164,6 +165,8 @@ static void named_pipe_auth_request(struct tevent_req *subreq) struct named_pipe_auth_req pipe_request; struct named_pipe_auth_rep pipe_reply; struct auth_context *auth_context; + uint32_t session_flags = 0; + struct dom_sid *anonymous_sid; NTSTATUS status; int ret; @@ -264,11 +267,23 @@ static void named_pipe_auth_request(struct tevent_req *subreq) goto reply; } + anonymous_sid = dom_sid_parse_talloc(auth_context, SID_NT_ANONYMOUS); + if (anonymous_sid == NULL) { + named_pipe_terminate_connection(pipe_conn, "Failed to parse Anonymous SID "); + talloc_free(auth_context); + return; + } + + session_flags = AUTH_SESSION_INFO_DEFAULT_GROUPS; + if (!dom_sid_equal(anonymous_sid, server_info->account_sid)) { + session_flags |= AUTH_SESSION_INFO_AUTHENTICATED; + } /* setup the session_info on the connection */ pipe_reply.status = auth_context->generate_session_info(conn, auth_context, server_info, + session_flags, &conn->session_info); talloc_free(auth_context); if (!NT_STATUS_IS_OK(pipe_reply.status)) { @@ -315,9 +330,22 @@ static void named_pipe_auth_request(struct tevent_req *subreq) goto reply; } + anonymous_sid = dom_sid_parse_talloc(auth_context, SID_NT_ANONYMOUS); + if (anonymous_sid == NULL) { + named_pipe_terminate_connection(pipe_conn, "Failed to parse Anonymous SID "); + talloc_free(auth_context); + return; + } + + session_flags = AUTH_SESSION_INFO_DEFAULT_GROUPS; + if (!dom_sid_equal(anonymous_sid, server_info->account_sid)) { + session_flags |= AUTH_SESSION_INFO_AUTHENTICATED; + } + pipe_reply.status = auth_context->generate_session_info(conn, auth_context, server_info, + session_flags, &conn->session_info); talloc_free(auth_context); if (!NT_STATUS_IS_OK(pipe_reply.status)) { @@ -405,10 +433,23 @@ static void named_pipe_auth_request(struct tevent_req *subreq) goto reply; } + anonymous_sid = dom_sid_parse_talloc(auth_context, SID_NT_ANONYMOUS); + if (anonymous_sid == NULL) { + named_pipe_terminate_connection(pipe_conn, "Failed to parse Anonymous SID "); + talloc_free(auth_context); + return; + } + + session_flags = AUTH_SESSION_INFO_DEFAULT_GROUPS; + if (!dom_sid_equal(anonymous_sid, server_info->account_sid)) { + session_flags |= AUTH_SESSION_INFO_AUTHENTICATED; + } + /* setup the session_info on the connection */ pipe_reply.status = auth_context->generate_session_info(conn, auth_context, server_info, + session_flags, &conn->session_info); talloc_free(auth_context); if (!NT_STATUS_IS_OK(pipe_reply.status)) { |