Coverage Report

Created: 2025-11-16 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/librpc/ndr/ndr_ntlmssp.c
Line
Count
Source
1
/*
2
   Unix SMB/CIFS implementation.
3
4
   routines for marshalling/unmarshalling special ntlmssp structures
5
6
   Copyright (C) Guenther Deschner 2009
7
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
18
   You should have received a copy of the GNU General Public License
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
*/
21
22
#include "includes.h"
23
#include "../librpc/gen_ndr/ndr_ntlmssp.h"
24
25
_PUBLIC_ size_t ndr_ntlmssp_string_length(uint32_t negotiate_flags, const char *s)
26
3.41k
{
27
3.41k
  if (!s) {
28
982
    return 0;
29
982
  }
30
31
2.42k
  if (negotiate_flags & NTLMSSP_NEGOTIATE_UNICODE) {
32
1.36k
    return strlen(s) * 2;
33
1.36k
  }
34
35
1.06k
  return strlen(s);
36
2.42k
}
37
38
_PUBLIC_ libndr_flags ndr_ntlmssp_negotiated_string_flags(uint32_t negotiate_flags)
39
5.85M
{
40
5.85M
  libndr_flags flags = LIBNDR_FLAG_STR_NOTERM |
41
5.85M
           LIBNDR_FLAG_STR_CHARLEN |
42
5.85M
           LIBNDR_FLAG_REMAINING;
43
44
5.85M
  if (!(negotiate_flags & NTLMSSP_NEGOTIATE_UNICODE)) {
45
5.26k
    flags |= LIBNDR_FLAG_STR_ASCII;
46
5.26k
  }
47
48
5.85M
  return flags;
49
5.85M
}
50
51
_PUBLIC_ enum ndr_err_code ndr_push_AV_PAIR_LIST(struct ndr_push *ndr, ndr_flags_type ndr_flags, const struct AV_PAIR_LIST *r)
52
1.22k
{
53
1.22k
  uint32_t cntr_pair_0;
54
1.22k
  if (ndr_flags & NDR_SCALARS) {
55
1.22k
    NDR_CHECK(ndr_push_align(ndr, 4));
56
1.13M
    for (cntr_pair_0 = 0; cntr_pair_0 < r->count; cntr_pair_0++) {
57
1.13M
      NDR_CHECK(ndr_push_AV_PAIR(ndr, NDR_SCALARS, &r->pair[cntr_pair_0]));
58
1.13M
    }
59
1.22k
  }
60
1.22k
  if (ndr_flags & NDR_BUFFERS) {
61
1.13M
    for (cntr_pair_0 = 0; cntr_pair_0 < r->count; cntr_pair_0++) {
62
1.13M
      NDR_CHECK(ndr_push_AV_PAIR(ndr, NDR_BUFFERS, &r->pair[cntr_pair_0]));
63
1.13M
    }
64
1.22k
  }
65
1.22k
  return NDR_ERR_SUCCESS;
66
1.22k
}
67
68
_PUBLIC_ enum ndr_err_code ndr_pull_AV_PAIR_LIST(struct ndr_pull *ndr, ndr_flags_type ndr_flags, struct AV_PAIR_LIST *r)
69
1.02k
{
70
1.02k
  uint32_t cntr_pair_0;
71
1.02k
  TALLOC_CTX *_mem_save_pair_0;
72
1.02k
  if (ndr_flags & NDR_SCALARS) {
73
1.02k
    uint32_t offset = 0;
74
1.02k
    NDR_CHECK(ndr_pull_align(ndr, 4));
75
1.02k
    r->count = 0;
76
1.02k
    if (ndr->data_size > 0) {
77
981
      NDR_PULL_NEED_BYTES(ndr, 4);
78
981
    }
79
1.80M
    while (offset + 4 <= ndr->data_size) {
80
1.80M
      uint16_t length;
81
1.80M
      uint16_t type;
82
1.80M
      type = SVAL(ndr->data + offset, 0);
83
1.80M
      if (type == MsvAvEOL) {
84
195
        r->count++;
85
195
        break;
86
195
      }
87
1.80M
      length = SVAL(ndr->data + offset, 2);
88
1.80M
      offset += length + 4;
89
1.80M
      r->count++;
90
1.80M
    }
91
1.01k
    NDR_PULL_ALLOC_N(ndr, r->pair, r->count);
92
1.01k
    _mem_save_pair_0 = NDR_PULL_GET_MEM_CTX(ndr);
93
1.01k
    NDR_PULL_SET_MEM_CTX(ndr, r->pair, 0);
94
1.68M
    for (cntr_pair_0 = 0; cntr_pair_0 < r->count; cntr_pair_0++) {
95
1.68M
      NDR_CHECK(ndr_pull_AV_PAIR(ndr, NDR_SCALARS, &r->pair[cntr_pair_0]));
96
1.68M
    }
97
794
    NDR_PULL_SET_MEM_CTX(ndr, _mem_save_pair_0, 0);
98
794
  }
99
794
  if (ndr_flags & NDR_BUFFERS) {
100
794
    _mem_save_pair_0 = NDR_PULL_GET_MEM_CTX(ndr);
101
794
    NDR_PULL_SET_MEM_CTX(ndr, r->pair, 0);
102
1.12M
    for (cntr_pair_0 = 0; cntr_pair_0 < r->count; cntr_pair_0++) {
103
1.12M
      NDR_CHECK(ndr_pull_AV_PAIR(ndr, NDR_BUFFERS, &r->pair[cntr_pair_0]));
104
1.12M
    }
105
794
    NDR_PULL_SET_MEM_CTX(ndr, _mem_save_pair_0, 0);
106
794
  }
107
794
  return NDR_ERR_SUCCESS;
108
794
}
109
110
_PUBLIC_ void ndr_print_ntlmssp_nt_response(TALLOC_CTX *mem_ctx,
111
              const DATA_BLOB *nt_response,
112
              bool ntlmv2)
113
0
{
114
0
  enum ndr_err_code ndr_err;
115
116
0
  if (ntlmv2) {
117
0
    struct NTLMv2_RESPONSE nt;
118
0
    if (nt_response->length > 24) {
119
0
      ndr_err = ndr_pull_struct_blob(nt_response, mem_ctx, &nt,
120
0
          (ndr_pull_flags_fn_t)ndr_pull_NTLMv2_RESPONSE);
121
0
      if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
122
0
        NDR_PRINT_DEBUG(NTLMv2_RESPONSE, &nt);
123
0
      }
124
0
    }
125
0
  } else {
126
0
    struct NTLM_RESPONSE nt;
127
0
    if (nt_response->length == 24) {
128
0
      ndr_err = ndr_pull_struct_blob(nt_response, mem_ctx, &nt,
129
0
          (ndr_pull_flags_fn_t)ndr_pull_NTLM_RESPONSE);
130
0
      if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
131
0
        NDR_PRINT_DEBUG(NTLM_RESPONSE, &nt);
132
0
      }
133
0
    }
134
0
  }
135
0
}
136
137
_PUBLIC_ void ndr_print_ntlmssp_lm_response(TALLOC_CTX *mem_ctx,
138
              const DATA_BLOB *lm_response,
139
              bool ntlmv2)
140
0
{
141
0
  enum ndr_err_code ndr_err;
142
143
0
  if (ntlmv2) {
144
0
    struct LMv2_RESPONSE lm;
145
0
    if (lm_response->length == 24) {
146
0
      ndr_err = ndr_pull_struct_blob(lm_response, mem_ctx, &lm,
147
0
          (ndr_pull_flags_fn_t)ndr_pull_LMv2_RESPONSE);
148
0
      if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
149
0
        NDR_PRINT_DEBUG(LMv2_RESPONSE, &lm);
150
0
      }
151
0
    }
152
0
  } else {
153
0
    struct LM_RESPONSE lm;
154
0
    if (lm_response->length == 24) {
155
0
      ndr_err = ndr_pull_struct_blob(lm_response, mem_ctx, &lm,
156
0
          (ndr_pull_flags_fn_t)ndr_pull_LM_RESPONSE);
157
0
      if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
158
0
        NDR_PRINT_DEBUG(LM_RESPONSE, &lm);
159
0
      }
160
0
    }
161
0
  }
162
0
}
163
164
_PUBLIC_ void ndr_print_ntlmssp_Version(struct ndr_print *ndr, const char *name, const union ntlmssp_Version *r)
165
551
{
166
551
  int level;
167
551
  level = ndr_print_steal_switch_value(ndr, r);
168
551
  switch (level) {
169
144
    case NTLMSSP_NEGOTIATE_VERSION:
170
144
      ndr_print_ntlmssp_VERSION(ndr, name, &r->version);
171
144
    break;
172
173
407
    default:
174
407
    break;
175
176
551
  }
177
551
}
178
179
_PUBLIC_ struct AV_PAIR *ndr_ntlmssp_find_av(const struct AV_PAIR_LIST *av_list,
180
               enum ntlmssp_AvId AvId)
181
0
{
182
0
  struct AV_PAIR *res = NULL;
183
0
  uint32_t i = 0;
184
185
0
  for (i = 0; i < av_list->count; i++) {
186
0
    if (av_list->pair[i].AvId != AvId) {
187
0
      continue;
188
0
    }
189
190
0
    res = discard_const_p(struct AV_PAIR, &av_list->pair[i]);
191
0
    break;
192
0
  }
193
194
0
  return res;
195
0
}