d90495fe9b580aa63460d380b45989154a5b7a77
[ira/wip.git] / librpc / ndr / ndr_ntlmssp.c
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/ndr/ndr_ntlmssp.h"
24 #include "../librpc/gen_ndr/ndr_ntlmssp.h"
25
26 _PUBLIC_ size_t ndr_ntlmssp_string_length(uint32_t negotiate_flags, const char *s)
27 {
28         if (!s) {
29                 return 0;
30         }
31
32         if (negotiate_flags & NTLMSSP_NEGOTIATE_UNICODE) {
33                 return strlen(s) * 2;
34         }
35
36         return strlen(s);
37 }
38
39 _PUBLIC_ uint32_t ndr_ntlmssp_negotiated_string_flags(uint32_t negotiate_flags)
40 {
41         uint32_t flags = LIBNDR_FLAG_STR_NOTERM |
42                          LIBNDR_FLAG_STR_CHARLEN |
43                          LIBNDR_FLAG_REMAINING;
44
45         if (!(negotiate_flags & NTLMSSP_NEGOTIATE_UNICODE)) {
46                 flags |= LIBNDR_FLAG_STR_ASCII;
47         }
48
49         return flags;
50 }
51
52 _PUBLIC_ enum ndr_err_code ndr_push_AV_PAIR_LIST(struct ndr_push *ndr, int ndr_flags, const struct AV_PAIR_LIST *r)
53 {
54         uint32_t cntr_pair_0;
55         if (ndr_flags & NDR_SCALARS) {
56                 NDR_CHECK(ndr_push_align(ndr, 4));
57                 for (cntr_pair_0 = 0; cntr_pair_0 < r->count; cntr_pair_0++) {
58                         NDR_CHECK(ndr_push_AV_PAIR(ndr, NDR_SCALARS, &r->pair[cntr_pair_0]));
59                 }
60         }
61         if (ndr_flags & NDR_BUFFERS) {
62                 for (cntr_pair_0 = 0; cntr_pair_0 < r->count; cntr_pair_0++) {
63                         NDR_CHECK(ndr_push_AV_PAIR(ndr, NDR_BUFFERS, &r->pair[cntr_pair_0]));
64                 }
65         }
66         return NDR_ERR_SUCCESS;
67 }
68
69 _PUBLIC_ enum ndr_err_code ndr_pull_AV_PAIR_LIST(struct ndr_pull *ndr, int ndr_flags, struct AV_PAIR_LIST *r)
70 {
71         uint32_t cntr_pair_0;
72         TALLOC_CTX *_mem_save_pair_0;
73         if (ndr_flags & NDR_SCALARS) {
74                 uint32_t offset = 0;
75                 NDR_CHECK(ndr_pull_align(ndr, 4));
76                 r->count = 0;
77                 if (ndr->data_size > 0) {
78                         NDR_PULL_NEED_BYTES(ndr, 4);
79                 }
80                 while (offset + 4 <= ndr->data_size) {
81                         uint16_t length;
82                         uint16_t type;
83                         type = SVAL(ndr->data + offset, 0);
84                         if (type == MsvAvEOL) {
85                                 r->count++;
86                                 break;
87                         }
88                         length = SVAL(ndr->data + offset, 2);
89                         offset += length + 4;
90                         r->count++;
91                 }
92                 NDR_PULL_ALLOC_N(ndr, r->pair, r->count);
93                 _mem_save_pair_0 = NDR_PULL_GET_MEM_CTX(ndr);
94                 NDR_PULL_SET_MEM_CTX(ndr, r->pair, 0);
95                 for (cntr_pair_0 = 0; cntr_pair_0 < r->count; cntr_pair_0++) {
96                         NDR_CHECK(ndr_pull_AV_PAIR(ndr, NDR_SCALARS, &r->pair[cntr_pair_0]));
97                 }
98                 NDR_PULL_SET_MEM_CTX(ndr, _mem_save_pair_0, 0);
99         }
100         if (ndr_flags & NDR_BUFFERS) {
101                 _mem_save_pair_0 = NDR_PULL_GET_MEM_CTX(ndr);
102                 NDR_PULL_SET_MEM_CTX(ndr, r->pair, 0);
103                 for (cntr_pair_0 = 0; cntr_pair_0 < r->count; cntr_pair_0++) {
104                         NDR_CHECK(ndr_pull_AV_PAIR(ndr, NDR_BUFFERS, &r->pair[cntr_pair_0]));
105                 }
106                 NDR_PULL_SET_MEM_CTX(ndr, _mem_save_pair_0, 0);
107         }
108         return NDR_ERR_SUCCESS;
109 }
110
111 _PUBLIC_ void ndr_print_ntlmssp_nt_response(TALLOC_CTX *mem_ctx,
112                                             struct smb_iconv_convenience *ic,
113                                             const DATA_BLOB *nt_response,
114                                             bool ntlmv2)
115 {
116         enum ndr_err_code ndr_err;
117
118         if (ntlmv2) {
119                 struct NTLMv2_RESPONSE nt;
120                 if (nt_response->length > 24) {
121                         ndr_err = ndr_pull_struct_blob(nt_response, mem_ctx, ic, &nt,
122                                         (ndr_pull_flags_fn_t)ndr_pull_NTLMv2_RESPONSE);
123                         if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
124                                 NDR_PRINT_DEBUG(NTLMv2_RESPONSE, &nt);
125                         }
126                 }
127         } else {
128                 struct NTLM_RESPONSE nt;
129                 if (nt_response->length == 24) {
130                         ndr_err = ndr_pull_struct_blob(nt_response, mem_ctx, ic, &nt,
131                                         (ndr_pull_flags_fn_t)ndr_pull_NTLM_RESPONSE);
132                         if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
133                                 NDR_PRINT_DEBUG(NTLM_RESPONSE, &nt);
134                         }
135                 }
136         }
137 }
138
139 _PUBLIC_ void ndr_print_ntlmssp_lm_response(TALLOC_CTX *mem_ctx,
140                                             struct smb_iconv_convenience *ic,
141                                             const DATA_BLOB *lm_response,
142                                             bool ntlmv2)
143 {
144         enum ndr_err_code ndr_err;
145
146         if (ntlmv2) {
147                 struct LMv2_RESPONSE lm;
148                 if (lm_response->length == 24) {
149                         ndr_err = ndr_pull_struct_blob(lm_response, mem_ctx, ic, &lm,
150                                         (ndr_pull_flags_fn_t)ndr_pull_LMv2_RESPONSE);
151                         if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
152                                 NDR_PRINT_DEBUG(LMv2_RESPONSE, &lm);
153                         }
154                 }
155         } else {
156                 struct LM_RESPONSE lm;
157                 if (lm_response->length == 24) {
158                         ndr_err = ndr_pull_struct_blob(lm_response, mem_ctx, ic, &lm,
159                                         (ndr_pull_flags_fn_t)ndr_pull_LM_RESPONSE);
160                         if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
161                                 NDR_PRINT_DEBUG(LM_RESPONSE, &lm);
162                         }
163                 }
164         }
165 }