#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,
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);
};
{
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);
}
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);
_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;
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);
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",
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);
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,
* @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;
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;
}
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]);
#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,
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;
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 (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);
- if (is_authenticated) {
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++;
}
}
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++;
+
}
}
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 */
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;
#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;
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;
call = talloc(pipe_conn, struct named_pipe_call);
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)) {
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)) {
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)) {