summaryrefslogtreecommitdiff
path: root/source3/rpc_server/dcesrv_auth_generic.c
blob: 77d76fc6c39c442f029e3b76ffb3baa10b5a6e3c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
 *  NTLMSSP Acceptor
 *  DCERPC Server functions
 *  Copyright (C) Simo Sorce 2010.
 *  Copyright (C) Andrew Bartlett 2011.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 */


#include "includes.h"
#include "rpc_server/dcesrv_auth_generic.h"
#include "auth.h"
#include "auth/gensec/gensec.h"

static NTSTATUS auth_generic_server_authtype_start_as_root(TALLOC_CTX *mem_ctx,
							   uint8_t auth_type, uint8_t auth_level,
							   DATA_BLOB *token_in,
							   DATA_BLOB *token_out,
							   const struct tsocket_address *remote_address,
							   struct gensec_security **ctx)
{
	struct gensec_security *gensec_security = NULL;
	NTSTATUS status;

	status = auth_generic_prepare(talloc_tos(), remote_address, &gensec_security);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, (__location__ ": auth_generic_prepare failed: %s\n",
			  nt_errstr(status)));
		return status;
	}

	status = gensec_start_mech_by_authtype(gensec_security, auth_type, auth_level);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, (__location__ ": auth_generic_start failed: %s\n",
			  nt_errstr(status)));
		TALLOC_FREE(gensec_security);
		return status;
	}

	status = gensec_update(gensec_security, mem_ctx, NULL, *token_in, token_out);
	if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
		DEBUG(2, (__location__ ": gensec_update failed: %s\n",
			  nt_errstr(status)));
		TALLOC_FREE(gensec_security);
		return status;
	}

	/* steal gensec context to the caller */
	*ctx = talloc_move(mem_ctx, &gensec_security);
	return NT_STATUS_OK;
}

NTSTATUS auth_generic_server_authtype_start(TALLOC_CTX *mem_ctx,
					    uint8_t auth_type, uint8_t auth_level,
					    DATA_BLOB *token_in,
					    DATA_BLOB *token_out,
					    const struct tsocket_address *remote_address,
					    struct gensec_security **ctx)
{
	NTSTATUS status;
	become_root();

	/* this has to be done as root in order to create the messaging socket */
	status = auth_generic_server_authtype_start_as_root(mem_ctx,
							    auth_type, auth_level,
							    token_in,
							    token_out,
							    remote_address,
							    ctx);
	unbecome_root();
	return status;
}

NTSTATUS auth_generic_server_step(struct gensec_security *gensec_security,
			     TALLOC_CTX *mem_ctx,
			     DATA_BLOB *token_in,
			     DATA_BLOB *token_out)
{
	NTSTATUS status;

	/* this has to be done as root in order to verify the password */
	become_root();
	status = gensec_update(gensec_security, mem_ctx, NULL, *token_in, token_out);
	unbecome_root();

	return status;
}

NTSTATUS auth_generic_server_check_flags(struct gensec_security *gensec_security,
				    bool do_sign, bool do_seal)
{
	if (do_sign && !gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
		DEBUG(1, (__location__ "Integrity was requested but client "
			  "failed to negotiate signing.\n"));
		return NT_STATUS_ACCESS_DENIED;
	}

	if (do_seal && !gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
		DEBUG(1, (__location__ "Privacy was requested but client "
			  "failed to negotiate sealing.\n"));
		return NT_STATUS_ACCESS_DENIED;
	}

	return NT_STATUS_OK;
}

NTSTATUS auth_generic_server_get_user_info(struct gensec_security *gensec_security,
				      TALLOC_CTX *mem_ctx,
				      struct auth_session_info **session_info)
{
	NTSTATUS status;

	/* this has to be done as root in order to get to the
	 * messaging sockets for IDMAP and privilege.ldb in the AD
	 * DC */
	become_root();
	status = gensec_session_info(gensec_security, mem_ctx, session_info);
	unbecome_root();
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(1, (__location__ ": Failed to get authenticated user "
			  "info: %s\n", nt_errstr(status)));
		return status;
	}

	DEBUG(5, (__location__ "OK: user: %s domain: %s\n",
		  (*session_info)->info->account_name,
		  (*session_info)->info->domain_name));

	return NT_STATUS_OK;
}