2 Unix SMB/CIFS implementation.
4 routines for marshalling/unmarshalling special NEGOEX structures
6 Copyright (C) Stefan Metzmacher 2015
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.
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.
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/>.
22 #include "librpc/gen_ndr/ndr_negoex.h"
23 #include "librpc/gen_ndr/ndr_misc.h"
24 #include "librpc/ndr/ndr_negoex.h"
26 void ndr_print_negoex_BYTE_VECTOR(struct ndr_print *ndr, const char *name, const struct negoex_BYTE_VECTOR *r)
28 ndr_print_struct(ndr, name, "negoex_BYTE_VECTOR");
29 if (r == NULL) { ndr_print_null(ndr); return; }
31 ndr_print_ptr(ndr, "data", r->data);
34 ndr_print_array_uint8(ndr, "data", r->data, r->length);
37 ndr_print_uint32(ndr, "length", r->length);
41 enum ndr_err_code ndr_push_negoex_BYTE_VECTOR(struct ndr_push *ndr, int ndr_flags, const struct negoex_BYTE_VECTOR *r)
43 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
44 if (ndr_flags & NDR_SCALARS) {
45 NDR_CHECK(ndr_push_align(ndr, 5));
46 NDR_CHECK(ndr_push_relative_ptr1(ndr, r->data));
47 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->length));
48 NDR_CHECK(ndr_push_trailer_align(ndr, 5));
50 if (ndr_flags & NDR_BUFFERS) {
52 NDR_CHECK(ndr_push_relative_ptr2_start(ndr, r->data));
54 NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, r->length));
56 NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->data, r->length));
57 NDR_CHECK(ndr_push_relative_ptr2_end(ndr, r->data));
60 return NDR_ERR_SUCCESS;
63 enum ndr_err_code ndr_pull_negoex_BYTE_VECTOR(struct ndr_pull *ndr, int ndr_flags, struct negoex_BYTE_VECTOR *r)
66 uint32_t size_data_1 = 0;
67 TALLOC_CTX *_mem_save_data_0 = NULL;
68 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
69 if (ndr_flags & NDR_SCALARS) {
70 NDR_CHECK(ndr_pull_align(ndr, 5));
71 NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_data));
73 NDR_PULL_ALLOC(ndr, r->data);
74 NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->data, _ptr_data));
78 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->length));
79 NDR_CHECK(ndr_pull_trailer_align(ndr, 5));
81 if (ndr_flags & NDR_BUFFERS) {
83 uint32_t _relative_save_offset;
84 _relative_save_offset = ndr->offset;
85 NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->data));
86 _mem_save_data_0 = NDR_PULL_GET_MEM_CTX(ndr);
87 NDR_PULL_SET_MEM_CTX(ndr, r->data, 0);
89 NDR_CHECK(ndr_pull_array_size(ndr, &r->data));
90 size_data_1 = ndr_get_array_size(ndr, &r->data);
92 size_data_1 = r->length;
94 NDR_PULL_ALLOC_N(ndr, r->data, size_data_1);
95 NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->data, size_data_1));
96 NDR_PULL_SET_MEM_CTX(ndr, _mem_save_data_0, 0);
97 if (ndr->offset > ndr->relative_highest_offset) {
98 ndr->relative_highest_offset = ndr->offset;
100 ndr->offset = _relative_save_offset;
104 NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->data, r->length));
108 return NDR_ERR_SUCCESS;
111 enum ndr_err_code ndr_push_negoex_AUTH_SCHEME_VECTOR(struct ndr_push *ndr, int ndr_flags, const struct negoex_AUTH_SCHEME_VECTOR *r)
113 uint32_t cntr_array_1;
114 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
115 if (ndr_flags & NDR_SCALARS) {
116 NDR_CHECK(ndr_push_align(ndr, 5));
117 NDR_CHECK(ndr_push_relative_ptr1(ndr, r->array));
118 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->count));
119 NDR_CHECK(ndr_push_trailer_align(ndr, 5));
121 if (ndr_flags & NDR_BUFFERS) {
123 NDR_CHECK(ndr_push_relative_ptr2_start(ndr, r->array));
125 NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, r->count));
127 for (cntr_array_1 = 0; cntr_array_1 < (r->count); cntr_array_1++) {
128 NDR_CHECK(ndr_push_negoex_AUTH_SCHEME(ndr, NDR_SCALARS, &r->array[cntr_array_1]));
130 NDR_CHECK(ndr_push_relative_ptr2_end(ndr, r->array));
133 return NDR_ERR_SUCCESS;
136 enum ndr_err_code ndr_pull_negoex_AUTH_SCHEME_VECTOR(struct ndr_pull *ndr, int ndr_flags, struct negoex_AUTH_SCHEME_VECTOR *r)
139 uint32_t size_array_1 = 0;
140 uint32_t cntr_array_1;
141 TALLOC_CTX *_mem_save_array_0 = NULL;
142 TALLOC_CTX *_mem_save_array_1 = NULL;
143 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
144 if (ndr_flags & NDR_SCALARS) {
145 NDR_CHECK(ndr_pull_align(ndr, 5));
146 NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_array));
148 NDR_PULL_ALLOC(ndr, r->array);
149 NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->array, _ptr_array));
153 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count));
154 NDR_CHECK(ndr_pull_trailer_align(ndr, 5));
156 if (ndr_flags & NDR_BUFFERS) {
158 uint32_t _relative_save_offset;
159 _relative_save_offset = ndr->offset;
160 NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->array));
161 _mem_save_array_0 = NDR_PULL_GET_MEM_CTX(ndr);
162 NDR_PULL_SET_MEM_CTX(ndr, r->array, 0);
164 NDR_CHECK(ndr_pull_array_size(ndr, &r->array));
165 size_array_1 = ndr_get_array_size(ndr, &r->array);
167 size_array_1 = r->count;
169 NDR_PULL_ALLOC_N(ndr, r->array, size_array_1);
170 _mem_save_array_1 = NDR_PULL_GET_MEM_CTX(ndr);
171 NDR_PULL_SET_MEM_CTX(ndr, r->array, 0);
172 for (cntr_array_1 = 0; cntr_array_1 < (size_array_1); cntr_array_1++) {
173 NDR_CHECK(ndr_pull_negoex_AUTH_SCHEME(ndr, NDR_SCALARS, &r->array[cntr_array_1]));
175 NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_1, 0);
176 NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_0, 0);
177 if (ndr->offset > ndr->relative_highest_offset) {
178 ndr->relative_highest_offset = ndr->offset;
180 ndr->offset = _relative_save_offset;
184 NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->array, r->count));
188 return NDR_ERR_SUCCESS;
191 enum ndr_err_code ndr_push_negoex_EXTENSION_VECTOR(struct ndr_push *ndr, int ndr_flags, const struct negoex_EXTENSION_VECTOR *r)
193 uint32_t cntr_array_1;
194 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
195 if (ndr_flags & NDR_SCALARS) {
196 NDR_CHECK(ndr_push_align(ndr, 5));
197 NDR_CHECK(ndr_push_relative_ptr1(ndr, r->array));
198 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->count));
199 NDR_CHECK(ndr_push_trailer_align(ndr, 5));
201 if (ndr_flags & NDR_BUFFERS) {
203 NDR_CHECK(ndr_push_relative_ptr2_start(ndr, r->array));
205 NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, r->count));
207 for (cntr_array_1 = 0; cntr_array_1 < (r->count); cntr_array_1++) {
208 NDR_CHECK(ndr_push_negoex_EXTENSION(ndr, NDR_SCALARS, &r->array[cntr_array_1]));
210 for (cntr_array_1 = 0; cntr_array_1 < (r->count); cntr_array_1++) {
211 NDR_CHECK(ndr_push_negoex_EXTENSION(ndr, NDR_BUFFERS, &r->array[cntr_array_1]));
213 NDR_CHECK(ndr_push_relative_ptr2_end(ndr, r->array));
216 return NDR_ERR_SUCCESS;
219 enum ndr_err_code ndr_pull_negoex_EXTENSION_VECTOR(struct ndr_pull *ndr, int ndr_flags, struct negoex_EXTENSION_VECTOR *r)
222 uint32_t size_array_1 = 0;
223 uint32_t cntr_array_1;
224 TALLOC_CTX *_mem_save_array_0 = NULL;
225 TALLOC_CTX *_mem_save_array_1 = NULL;
226 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
227 if (ndr_flags & NDR_SCALARS) {
228 NDR_CHECK(ndr_pull_align(ndr, 5));
229 NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_array));
231 NDR_PULL_ALLOC(ndr, r->array);
232 NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->array, _ptr_array));
236 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count));
237 NDR_CHECK(ndr_pull_trailer_align(ndr, 5));
239 if (ndr_flags & NDR_BUFFERS) {
241 uint32_t _relative_save_offset;
242 _relative_save_offset = ndr->offset;
243 NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->array));
244 _mem_save_array_0 = NDR_PULL_GET_MEM_CTX(ndr);
245 NDR_PULL_SET_MEM_CTX(ndr, r->array, 0);
247 NDR_CHECK(ndr_pull_array_size(ndr, &r->array));
248 size_array_1 = ndr_get_array_size(ndr, &r->array);
250 size_array_1 = r->count;
252 NDR_PULL_ALLOC_N(ndr, r->array, size_array_1);
253 _mem_save_array_1 = NDR_PULL_GET_MEM_CTX(ndr);
254 NDR_PULL_SET_MEM_CTX(ndr, r->array, 0);
255 for (cntr_array_1 = 0; cntr_array_1 < (size_array_1); cntr_array_1++) {
256 NDR_CHECK(ndr_pull_negoex_EXTENSION(ndr, NDR_SCALARS, &r->array[cntr_array_1]));
258 for (cntr_array_1 = 0; cntr_array_1 < (size_array_1); cntr_array_1++) {
259 NDR_CHECK(ndr_pull_negoex_EXTENSION(ndr, NDR_BUFFERS, &r->array[cntr_array_1]));
261 NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_1, 0);
262 NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_0, 0);
263 if (ndr->offset > ndr->relative_highest_offset) {
264 ndr->relative_highest_offset = ndr->offset;
266 ndr->offset = _relative_save_offset;
270 NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->array, r->count));
274 return NDR_ERR_SUCCESS;
277 enum ndr_err_code ndr_push_negoex_ALERT_VECTOR(struct ndr_push *ndr, int ndr_flags, const struct negoex_ALERT_VECTOR *r)
279 uint32_t cntr_array_1;
280 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
281 if (ndr_flags & NDR_SCALARS) {
282 NDR_CHECK(ndr_push_align(ndr, 5));
283 NDR_CHECK(ndr_push_relative_ptr1(ndr, r->array));
284 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->count));
285 NDR_CHECK(ndr_push_trailer_align(ndr, 5));
287 if (ndr_flags & NDR_BUFFERS) {
289 NDR_CHECK(ndr_push_relative_ptr2_start(ndr, r->array));
291 NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, r->count));
293 for (cntr_array_1 = 0; cntr_array_1 < (r->count); cntr_array_1++) {
294 NDR_CHECK(ndr_push_negoex_ALERT(ndr, NDR_SCALARS, &r->array[cntr_array_1]));
296 for (cntr_array_1 = 0; cntr_array_1 < (r->count); cntr_array_1++) {
297 NDR_CHECK(ndr_push_negoex_ALERT(ndr, NDR_BUFFERS, &r->array[cntr_array_1]));
299 NDR_CHECK(ndr_push_relative_ptr2_end(ndr, r->array));
302 return NDR_ERR_SUCCESS;
305 enum ndr_err_code ndr_pull_negoex_ALERT_VECTOR(struct ndr_pull *ndr, int ndr_flags, struct negoex_ALERT_VECTOR *r)
308 uint32_t size_array_1 = 0;
309 uint32_t cntr_array_1;
310 TALLOC_CTX *_mem_save_array_0 = NULL;
311 TALLOC_CTX *_mem_save_array_1 = NULL;
312 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
313 if (ndr_flags & NDR_SCALARS) {
314 NDR_CHECK(ndr_pull_align(ndr, 5));
315 NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_array));
317 NDR_PULL_ALLOC(ndr, r->array);
318 NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->array, _ptr_array));
322 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count));
323 NDR_CHECK(ndr_pull_trailer_align(ndr, 5));
325 if (ndr_flags & NDR_BUFFERS) {
327 uint32_t _relative_save_offset;
328 _relative_save_offset = ndr->offset;
329 NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->array));
330 _mem_save_array_0 = NDR_PULL_GET_MEM_CTX(ndr);
331 NDR_PULL_SET_MEM_CTX(ndr, r->array, 0);
333 NDR_CHECK(ndr_pull_array_size(ndr, &r->array));
334 size_array_1 = ndr_get_array_size(ndr, &r->array);
336 size_array_1 = r->count;
338 NDR_PULL_ALLOC_N(ndr, r->array, size_array_1);
339 _mem_save_array_1 = NDR_PULL_GET_MEM_CTX(ndr);
340 NDR_PULL_SET_MEM_CTX(ndr, r->array, 0);
341 for (cntr_array_1 = 0; cntr_array_1 < (size_array_1); cntr_array_1++) {
342 NDR_CHECK(ndr_pull_negoex_ALERT(ndr, NDR_SCALARS, &r->array[cntr_array_1]));
344 for (cntr_array_1 = 0; cntr_array_1 < (size_array_1); cntr_array_1++) {
345 NDR_CHECK(ndr_pull_negoex_ALERT(ndr, NDR_BUFFERS, &r->array[cntr_array_1]));
347 NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_1, 0);
348 NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_0, 0);
349 if (ndr->offset > ndr->relative_highest_offset) {
350 ndr->relative_highest_offset = ndr->offset;
352 ndr->offset = _relative_save_offset;
356 NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->array, r->count));
360 return NDR_ERR_SUCCESS;
363 size_t ndr_negoex_MESSAGE_header_length(const struct negoex_MESSAGE *r)
367 size += 8; /* signature */
368 size += 4; /* type */
369 size += 4; /* sequence_number */
370 size += 4; /* header_length */
371 size += 4; /* message_length */
372 size += 16; /* conversation_id */
375 case NEGOEX_MESSAGE_TYPE_INITIATOR_NEGO:
376 case NEGOEX_MESSAGE_TYPE_ACCEPTOR_NEGO:
377 size += 32; /* random */
378 size += 8; /* protocol_version */
379 size += 8; /* auth_schemes */
380 size += 8; /* extensions */
383 case NEGOEX_MESSAGE_TYPE_INITIATOR_META_DATA:
384 case NEGOEX_MESSAGE_TYPE_ACCEPTOR_META_DATA:
385 case NEGOEX_MESSAGE_TYPE_CHALLENGE:
386 case NEGOEX_MESSAGE_TYPE_AP_REQUEST:
387 size += 16; /* auth_scheme */
388 size += 8; /* exchange */
391 case NEGOEX_MESSAGE_TYPE_VERIFY:
392 size += 16; /* auth_scheme */
393 size += 4; /* checksum.header_length */
394 size += 4; /* checksum.scheme */
395 size += 4; /* checksum.type */
396 size += 8; /* checksum.value */
399 case NEGOEX_MESSAGE_TYPE_ALERT:
400 size += 16; /* auth_scheme */
401 size += 4; /* status */
402 size += 8; /* alerts */
409 enum ndr_err_code ndr_pull_negoex_MESSAGE(struct ndr_pull *ndr, int ndr_flags, struct negoex_MESSAGE *r)
411 uint32_t _save_relative_base_offset = ndr_pull_get_relative_base_offset(ndr);
412 uint32_t size_signature_0 = 0;
413 uint32_t start_data_size = ndr->data_size;
414 uint32_t saved_offset = 0;
415 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
416 if (ndr_flags & NDR_SCALARS) {
417 NDR_CHECK(ndr_pull_align(ndr, 5));
418 NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, r, ndr->offset));
419 size_signature_0 = 8;
420 NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->signature, size_signature_0, sizeof(uint8_t), CH_DOS));
421 NDR_CHECK(ndr_pull_negoex_MESSAGE_TYPE(ndr, NDR_SCALARS, &r->type));
422 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sequence_number));
423 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->header_length));
424 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->message_length));
425 saved_offset = ndr->offset;
426 ndr->offset = ndr->relative_base_offset;
427 NDR_PULL_NEED_BYTES(ndr, r->message_length);
428 ndr->data_size = ndr->offset + r->message_length;
429 ndr->offset = saved_offset;
430 NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->conversation_id));
431 NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->p, r->type));
432 NDR_CHECK(ndr_pull_negoex_PAYLOAD(ndr, NDR_SCALARS, &r->p));
433 NDR_CHECK(ndr_pull_trailer_align(ndr, 5));
434 ndr->offset = ndr->data_size;
435 ndr->data_size = start_data_size;
437 if (ndr_flags & NDR_BUFFERS) {
438 NDR_CHECK(ndr_pull_setup_relative_base_offset2(ndr, r));
439 saved_offset = ndr->offset;
440 ndr->offset = ndr->relative_base_offset;
441 NDR_PULL_NEED_BYTES(ndr, r->message_length);
442 ndr->data_size = ndr->offset + r->message_length;
443 ndr->offset = saved_offset;
444 NDR_CHECK(ndr_pull_negoex_PAYLOAD(ndr, NDR_BUFFERS, &r->p));
445 ndr->offset = ndr->data_size;
446 ndr->data_size = start_data_size;
448 ndr_pull_restore_relative_base_offset(ndr, _save_relative_base_offset);
449 return NDR_ERR_SUCCESS;
452 enum ndr_err_code ndr_push_negoex_MESSAGE_ARRAY(struct ndr_push *ndr, int ndr_flags, const struct negoex_MESSAGE_ARRAY *r)
454 uint32_t cntr_messages_0;
456 uint32_t _flags_save_STRUCT = ndr->flags;
457 ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
458 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
459 if (ndr_flags & NDR_SCALARS) {
460 NDR_CHECK(ndr_push_align(ndr, 5));
461 for (cntr_messages_0 = 0; cntr_messages_0 < (r->count); cntr_messages_0++) {
462 NDR_CHECK(ndr_push_negoex_MESSAGE(ndr, NDR_SCALARS|NDR_BUFFERS, &r->messages[cntr_messages_0]));
464 NDR_CHECK(ndr_push_trailer_align(ndr, 5));
466 ndr->flags = _flags_save_STRUCT;
468 return NDR_ERR_SUCCESS;
471 enum ndr_err_code ndr_pull_negoex_MESSAGE_ARRAY(struct ndr_pull *ndr, int ndr_flags, struct negoex_MESSAGE_ARRAY *r)
473 uint32_t size_messages_0 = 0;
474 uint32_t cntr_messages_0;
475 TALLOC_CTX *_mem_save_messages_0 = NULL;
477 uint32_t _flags_save_STRUCT = ndr->flags;
478 ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
479 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
480 if (ndr_flags & NDR_SCALARS) {
481 uint32_t saved_offset = ndr->offset;
482 uint32_t available = 0;
483 NDR_CHECK(ndr_pull_align(ndr, 5));
485 available = ndr->data_size - ndr->offset;
486 while (available > 0) {
490 * The common header is 40 bytes
491 * and message_length is at offset 20
493 NDR_PULL_NEED_BYTES(ndr, 40);
495 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &length));
499 * let the pull function catch the error
503 NDR_PULL_NEED_BYTES(ndr, length);
504 ndr->offset += length;
508 ndr->offset = saved_offset;
509 size_messages_0 = r->count;
510 NDR_PULL_ALLOC_N(ndr, r->messages, size_messages_0);
511 _mem_save_messages_0 = NDR_PULL_GET_MEM_CTX(ndr);
512 NDR_PULL_SET_MEM_CTX(ndr, r->messages, 0);
513 for (cntr_messages_0 = 0; cntr_messages_0 < (size_messages_0); cntr_messages_0++) {
514 NDR_CHECK(ndr_pull_negoex_MESSAGE(ndr, NDR_SCALARS|NDR_BUFFERS, &r->messages[cntr_messages_0]));
516 NDR_PULL_SET_MEM_CTX(ndr, _mem_save_messages_0, 0);
517 NDR_CHECK(ndr_pull_trailer_align(ndr, 5));
519 ndr->flags = _flags_save_STRUCT;
521 return NDR_ERR_SUCCESS;