~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/auth/auth_ntlmssp.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
   Unix SMB/Netbios implementation.
 
3
   Version 3.0
 
4
   handle NLTMSSP, server side
 
5
 
 
6
   Copyright (C) Andrew Tridgell      2001
 
7
   Copyright (C) Andrew Bartlett 2001-2003
 
8
 
 
9
   This program is free software; you can redistribute it and/or modify
 
10
   it under the terms of the GNU General Public License as published by
 
11
   the Free Software Foundation; either version 3 of the License, or
 
12
   (at your option) any later version.
 
13
   
 
14
   This program is distributed in the hope that it will be useful,
 
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
   GNU General Public License for more details.
 
18
   
 
19
   You should have received a copy of the GNU General Public License
 
20
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
21
*/
 
22
 
 
23
#include "includes.h"
 
24
 
 
25
/**
 
26
 * Return the challenge as determined by the authentication subsystem 
 
27
 * @return an 8 byte random challenge
 
28
 */
 
29
 
 
30
static void auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state,
 
31
                                       uint8_t chal[8])
 
32
{
 
33
        AUTH_NTLMSSP_STATE *auth_ntlmssp_state =
 
34
                (AUTH_NTLMSSP_STATE *)ntlmssp_state->auth_context;
 
35
        auth_ntlmssp_state->auth_context->get_ntlm_challenge(
 
36
                auth_ntlmssp_state->auth_context, chal);
 
37
}
 
38
 
 
39
/**
 
40
 * Some authentication methods 'fix' the challenge, so we may not be able to set it
 
41
 *
 
42
 * @return If the effective challenge used by the auth subsystem may be modified
 
43
 */
 
44
static bool auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
 
45
{
 
46
        AUTH_NTLMSSP_STATE *auth_ntlmssp_state =
 
47
                (AUTH_NTLMSSP_STATE *)ntlmssp_state->auth_context;
 
48
        struct auth_context *auth_context = auth_ntlmssp_state->auth_context;
 
49
 
 
50
        return auth_context->challenge_may_be_modified;
 
51
}
 
52
 
 
53
/**
 
54
 * NTLM2 authentication modifies the effective challenge, 
 
55
 * @param challenge The new challenge value
 
56
 */
 
57
static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
 
58
{
 
59
        AUTH_NTLMSSP_STATE *auth_ntlmssp_state =
 
60
                (AUTH_NTLMSSP_STATE *)ntlmssp_state->auth_context;
 
61
        struct auth_context *auth_context = auth_ntlmssp_state->auth_context;
 
62
 
 
63
        SMB_ASSERT(challenge->length == 8);
 
64
 
 
65
        auth_context->challenge = data_blob_talloc(auth_context->mem_ctx, 
 
66
                                                   challenge->data, challenge->length);
 
67
 
 
68
        auth_context->challenge_set_by = "NTLMSSP callback (NTLM2)";
 
69
 
 
70
        DEBUG(5, ("auth_context challenge set by %s\n", auth_context->challenge_set_by));
 
71
        DEBUG(5, ("challenge is: \n"));
 
72
        dump_data(5, auth_context->challenge.data, auth_context->challenge.length);
 
73
        return NT_STATUS_OK;
 
74
}
 
75
 
 
76
/**
 
77
 * Check the password on an NTLMSSP login.  
 
78
 *
 
79
 * Return the session keys used on the connection.
 
80
 */
 
81
 
 
82
static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) 
 
83
{
 
84
        AUTH_NTLMSSP_STATE *auth_ntlmssp_state =
 
85
                (AUTH_NTLMSSP_STATE *)ntlmssp_state->auth_context;
 
86
        auth_usersupplied_info *user_info = NULL;
 
87
        NTSTATUS nt_status;
 
88
        bool username_was_mapped;
 
89
 
 
90
        /* the client has given us its machine name (which we otherwise would not get on port 445).
 
91
           we need to possibly reload smb.conf if smb.conf includes depend on the machine name */
 
92
 
 
93
        set_remote_machine_name(auth_ntlmssp_state->ntlmssp_state->workstation, True);
 
94
 
 
95
        /* setup the string used by %U */
 
96
        /* sub_set_smb_name checks for weird internally */
 
97
        sub_set_smb_name(auth_ntlmssp_state->ntlmssp_state->user);
 
98
 
 
99
        reload_services(True);
 
100
 
 
101
        nt_status = make_user_info_map(&user_info, 
 
102
                                       auth_ntlmssp_state->ntlmssp_state->user, 
 
103
                                       auth_ntlmssp_state->ntlmssp_state->domain, 
 
104
                                       auth_ntlmssp_state->ntlmssp_state->workstation, 
 
105
                                       auth_ntlmssp_state->ntlmssp_state->lm_resp.data ? &auth_ntlmssp_state->ntlmssp_state->lm_resp : NULL, 
 
106
                                       auth_ntlmssp_state->ntlmssp_state->nt_resp.data ? &auth_ntlmssp_state->ntlmssp_state->nt_resp : NULL, 
 
107
                                       NULL, NULL, NULL,
 
108
                                       True);
 
109
 
 
110
        user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
 
111
 
 
112
        if (!NT_STATUS_IS_OK(nt_status)) {
 
113
                return nt_status;
 
114
        }
 
115
 
 
116
        nt_status = auth_ntlmssp_state->auth_context->check_ntlm_password(auth_ntlmssp_state->auth_context, 
 
117
                                                                          user_info, &auth_ntlmssp_state->server_info); 
 
118
 
 
119
        username_was_mapped = user_info->was_mapped;
 
120
 
 
121
        free_user_info(&user_info);
 
122
 
 
123
        if (!NT_STATUS_IS_OK(nt_status)) {
 
124
                return nt_status;
 
125
        }
 
126
 
 
127
        auth_ntlmssp_state->server_info->nss_token |= username_was_mapped;
 
128
 
 
129
        nt_status = create_local_token(auth_ntlmssp_state->server_info);
 
130
 
 
131
        if (!NT_STATUS_IS_OK(nt_status)) {
 
132
                DEBUG(10, ("create_local_token failed: %s\n",
 
133
                        nt_errstr(nt_status)));
 
134
                return nt_status;
 
135
        }
 
136
 
 
137
        if (auth_ntlmssp_state->server_info->user_session_key.length) {
 
138
                DEBUG(10, ("Got NT session key of length %u\n",
 
139
                        (unsigned int)auth_ntlmssp_state->server_info->user_session_key.length));
 
140
                *user_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx, 
 
141
                                                   auth_ntlmssp_state->server_info->user_session_key.data,
 
142
                                                   auth_ntlmssp_state->server_info->user_session_key.length);
 
143
        }
 
144
        if (auth_ntlmssp_state->server_info->lm_session_key.length) {
 
145
                DEBUG(10, ("Got LM session key of length %u\n",
 
146
                        (unsigned int)auth_ntlmssp_state->server_info->lm_session_key.length));
 
147
                *lm_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx, 
 
148
                                                   auth_ntlmssp_state->server_info->lm_session_key.data,
 
149
                                                   auth_ntlmssp_state->server_info->lm_session_key.length);
 
150
        }
 
151
        return nt_status;
 
152
}
 
153
 
 
154
NTSTATUS auth_ntlmssp_start(AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
 
155
{
 
156
        NTSTATUS nt_status;
 
157
        TALLOC_CTX *mem_ctx;
 
158
 
 
159
        mem_ctx = talloc_init("AUTH NTLMSSP context");
 
160
        
 
161
        *auth_ntlmssp_state = TALLOC_ZERO_P(mem_ctx, AUTH_NTLMSSP_STATE);
 
162
        if (!*auth_ntlmssp_state) {
 
163
                DEBUG(0,("auth_ntlmssp_start: talloc failed!\n"));
 
164
                talloc_destroy(mem_ctx);
 
165
                return NT_STATUS_NO_MEMORY;
 
166
        }
 
167
 
 
168
        ZERO_STRUCTP(*auth_ntlmssp_state);
 
169
 
 
170
        (*auth_ntlmssp_state)->mem_ctx = mem_ctx;
 
171
 
 
172
        if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_start(&(*auth_ntlmssp_state)->ntlmssp_state))) {
 
173
                return nt_status;
 
174
        }
 
175
 
 
176
        if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&(*auth_ntlmssp_state)->auth_context))) {
 
177
                return nt_status;
 
178
        }
 
179
 
 
180
        (*auth_ntlmssp_state)->ntlmssp_state->auth_context = (*auth_ntlmssp_state);
 
181
        (*auth_ntlmssp_state)->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
 
182
        (*auth_ntlmssp_state)->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
 
183
        (*auth_ntlmssp_state)->ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
 
184
        (*auth_ntlmssp_state)->ntlmssp_state->check_password = auth_ntlmssp_check_password;
 
185
        (*auth_ntlmssp_state)->ntlmssp_state->server_role = (enum server_types)lp_server_role();
 
186
 
 
187
        return NT_STATUS_OK;
 
188
}
 
189
 
 
190
void auth_ntlmssp_end(AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
 
191
{
 
192
        TALLOC_CTX *mem_ctx;
 
193
 
 
194
        if (*auth_ntlmssp_state == NULL) {
 
195
                return;
 
196
        }
 
197
 
 
198
        mem_ctx = (*auth_ntlmssp_state)->mem_ctx;
 
199
        if ((*auth_ntlmssp_state)->ntlmssp_state) {
 
200
                ntlmssp_end(&(*auth_ntlmssp_state)->ntlmssp_state);
 
201
        }
 
202
        if ((*auth_ntlmssp_state)->auth_context) {
 
203
                ((*auth_ntlmssp_state)->auth_context->free)(&(*auth_ntlmssp_state)->auth_context);
 
204
        }
 
205
        if ((*auth_ntlmssp_state)->server_info) {
 
206
                TALLOC_FREE((*auth_ntlmssp_state)->server_info);
 
207
        }
 
208
        talloc_destroy(mem_ctx);
 
209
        *auth_ntlmssp_state = NULL;
 
210
}
 
211
 
 
212
NTSTATUS auth_ntlmssp_update(AUTH_NTLMSSP_STATE *auth_ntlmssp_state, 
 
213
                             const DATA_BLOB request, DATA_BLOB *reply) 
 
214
{
 
215
        return ntlmssp_update(auth_ntlmssp_state->ntlmssp_state, request, reply);
 
216
}