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