summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/auth/auth.h5
-rw-r--r--source4/auth/gensec/gensec.c8
-rw-r--r--source4/auth/ntlm/auth_simple.c8
-rw-r--r--source4/auth/session.c7
-rw-r--r--source4/auth/session.h1
-rw-r--r--source4/auth/system_session.c12
-rw-r--r--source4/dsdb/samdb/ldb_modules/operational.c20
-rw-r--r--source4/dsdb/samdb/samdb.c61
-rw-r--r--source4/smb_server/smb/sesssetup.c14
-rw-r--r--source4/smbd/service_named_pipe.c41
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)) {