Coverage Report

Created: 2025-12-31 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/auth/ntlmssp/gensec_ntlmssp_server.c
Line
Count
Source
1
/*
2
   Unix SMB/Netbios implementation.
3
   Version 3.0
4
   handle NLTMSSP, client server side parsing
5
6
   Copyright (C) Andrew Tridgell      2001
7
   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2001-2005
8
   Copyright (C) Stefan Metzmacher 2005
9
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 3 of the License, or
13
   (at your option) any later version.
14
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
20
   You should have received a copy of the GNU General Public License
21
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
*/
23
24
#include "includes.h"
25
#include "system/network.h"
26
#include "lib/tsocket/tsocket.h"
27
#include "auth/ntlmssp/ntlmssp.h"
28
#include "../librpc/gen_ndr/ndr_ntlmssp.h"
29
#include "auth/ntlmssp/ntlmssp_ndr.h"
30
#include "auth/ntlmssp/ntlmssp_private.h"
31
#include "../libcli/auth/libcli_auth.h"
32
#include "../lib/crypto/crypto.h"
33
#include "auth/gensec/gensec.h"
34
#include "auth/gensec/gensec_internal.h"
35
#include "auth/common_auth.h"
36
#include "param/param.h"
37
#include "param/loadparm.h"
38
#include "libds/common/roles.h"
39
40
#undef DBGC_CLASS
41
0
#define DBGC_CLASS DBGC_AUTH
42
43
/**
44
 * Return the credentials of a logged on user, including session keys
45
 * etc.
46
 *
47
 * Only valid after a successful authentication
48
 *
49
 * May only be called once per authentication.
50
 *
51
 */
52
53
NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_security,
54
             TALLOC_CTX *mem_ctx,
55
             struct auth_session_info **session_info)
56
0
{
57
0
  NTSTATUS nt_status;
58
0
  struct gensec_ntlmssp_context *gensec_ntlmssp =
59
0
    talloc_get_type_abort(gensec_security->private_data,
60
0
              struct gensec_ntlmssp_context);
61
0
  uint32_t session_info_flags = 0;
62
63
0
  if (gensec_security->want_features & GENSEC_FEATURE_UNIX_TOKEN) {
64
0
    session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN;
65
0
  }
66
67
0
  session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS;
68
0
  session_info_flags |= AUTH_SESSION_INFO_NTLM;
69
70
0
  if (gensec_security->auth_context && gensec_security->auth_context->generate_session_info) {
71
0
    nt_status = gensec_security->auth_context->generate_session_info(gensec_security->auth_context, mem_ctx,
72
0
                     gensec_ntlmssp->server_returned_info,
73
0
                     gensec_ntlmssp->ntlmssp_state->user,
74
0
                     session_info_flags,
75
0
                     session_info);
76
0
  } else {
77
0
    DEBUG(0, ("Cannot generate a session_info without the auth_context\n"));
78
0
    return NT_STATUS_INTERNAL_ERROR;
79
0
  }
80
81
0
  NT_STATUS_NOT_OK_RETURN(nt_status);
82
83
0
  nt_status = gensec_ntlmssp_session_key(gensec_security, *session_info,
84
0
                 &(*session_info)->session_key);
85
0
  if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_USER_SESSION_KEY)) {
86
0
    (*session_info)->session_key = data_blob_null;
87
0
    nt_status = NT_STATUS_OK;
88
0
  }
89
90
0
  return nt_status;
91
0
}
92
93
/**
94
 * Start NTLMSSP on the server side
95
 *
96
 */
97
NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security)
98
0
{
99
0
  NTSTATUS nt_status;
100
0
  struct ntlmssp_state *ntlmssp_state;
101
0
  struct gensec_ntlmssp_context *gensec_ntlmssp;
102
0
  const char *netbios_name;
103
0
  const char *netbios_domain;
104
0
  const char *dns_name;
105
0
  const char *dns_domain;
106
0
  enum server_role role;
107
108
0
  role = lpcfg_server_role(gensec_security->settings->lp_ctx);
109
110
0
  nt_status = gensec_ntlmssp_start(gensec_security);
111
0
  NT_STATUS_NOT_OK_RETURN(nt_status);
112
113
0
  gensec_ntlmssp =
114
0
    talloc_get_type_abort(gensec_security->private_data,
115
0
              struct gensec_ntlmssp_context);
116
117
0
  ntlmssp_state = talloc_zero(gensec_ntlmssp,
118
0
            struct ntlmssp_state);
119
0
  if (!ntlmssp_state) {
120
0
    return NT_STATUS_NO_MEMORY;
121
0
  }
122
0
  gensec_ntlmssp->ntlmssp_state = ntlmssp_state;
123
124
0
  ntlmssp_state->role = NTLMSSP_SERVER;
125
126
0
  ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;
127
128
0
  ntlmssp_state->allow_lm_response =
129
0
    lpcfg_lanman_auth(gensec_security->settings->lp_ctx);
130
131
0
  if (ntlmssp_state->allow_lm_response &&
132
0
      gensec_setting_bool(gensec_security->settings,
133
0
        "ntlmssp_server", "allow_lm_key", false))
134
0
  {
135
0
    ntlmssp_state->allow_lm_key = true;
136
0
  }
137
138
0
  ntlmssp_state->force_old_spnego = false;
139
140
0
  if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "force_old_spnego", false)) {
141
    /*
142
     * For testing Windows 2000 mode
143
     */
144
0
    ntlmssp_state->force_old_spnego = true;
145
0
  }
146
147
0
  ntlmssp_state->neg_flags =
148
0
    NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_VERSION;
149
150
0
  if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "128bit", true)) {
151
0
    ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;
152
0
  }
153
154
0
  if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "56bit", true)) {
155
0
    ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
156
0
  }
157
158
0
  if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "keyexchange", true)) {
159
0
    ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
160
0
  }
161
162
0
  if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "alwayssign", true)) {
163
0
    ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
164
0
  }
165
166
0
  if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "ntlm2", true)) {
167
0
    ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
168
0
  }
169
170
0
  if (ntlmssp_state->allow_lm_key) {
171
0
    ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
172
0
  }
173
174
  /*
175
   * We always allow NTLMSSP_NEGOTIATE_SIGN and NTLMSSP_NEGOTIATE_SEAL.
176
   *
177
   * These will be removed if the client doesn't want them.
178
   */
179
0
  ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
180
0
  ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
181
182
183
0
  if (role == ROLE_STANDALONE) {
184
0
    ntlmssp_state->server.is_standalone = true;
185
0
  } else {
186
0
    ntlmssp_state->server.is_standalone = false;
187
0
  }
188
189
0
  if (gensec_security->settings->server_netbios_name) {
190
0
    netbios_name = gensec_security->settings->server_netbios_name;
191
0
  } else {
192
0
    netbios_name = lpcfg_netbios_name(gensec_security->settings->lp_ctx);
193
0
  }
194
195
0
  if (gensec_security->settings->server_netbios_domain) {
196
0
    netbios_domain = gensec_security->settings->server_netbios_domain;
197
0
  } else {
198
0
    netbios_domain = lpcfg_workgroup(gensec_security->settings->lp_ctx);
199
0
  }
200
201
0
  if (gensec_security->settings->server_dns_name) {
202
0
    dns_name = gensec_security->settings->server_dns_name;
203
0
  } else {
204
0
    dns_name = lpcfg_dns_hostname(gensec_security->settings->lp_ctx);
205
0
  }
206
207
0
  if (gensec_security->settings->server_dns_domain) {
208
0
    dns_domain = gensec_security->settings->server_dns_domain;
209
0
  } else {
210
0
    dns_domain = lpcfg_dnsdomain(gensec_security->settings->lp_ctx);
211
0
  }
212
213
0
  ntlmssp_state->server.netbios_name = talloc_strdup(ntlmssp_state, netbios_name);
214
0
  NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.netbios_name);
215
216
0
  ntlmssp_state->server.netbios_domain = talloc_strdup(ntlmssp_state, netbios_domain);
217
0
  NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.netbios_domain);
218
219
0
  ntlmssp_state->server.dns_name = talloc_strdup(ntlmssp_state, dns_name);
220
0
  NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_name);
221
222
0
  ntlmssp_state->server.dns_domain = talloc_strdup(ntlmssp_state, dns_domain);
223
0
  NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_domain);
224
225
0
  ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
226
0
  ntlmssp_state->conf_flags = ntlmssp_state->neg_flags;
227
228
0
  return NT_STATUS_OK;
229
0
}
230