/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 | } |