2 * Unix SMB/CIFS implementation.
5 * http://msdn.microsoft.com/en-us/library/cc232006%28v=PROT.13%29.aspx
7 * Copyright (C) Volker Lendecke 2011
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "include/client.h"
25 #include "libsmb/proto.h"
26 #include "include/ntioctl.h"
28 bool symlink_reparse_buffer_marshall(
29 const char *substitute
, const char *printname
, uint32_t flags
,
30 TALLOC_CTX
*mem_ctx
, uint8_t **pdst
, size_t *pdstlen
)
34 uint8_t *subst_utf16
= NULL
;
35 uint8_t *print_utf16
= NULL
;
39 if (substitute
== NULL
) {
42 if (printname
== NULL
) {
43 printname
= substitute
;
46 if (!convert_string_talloc(talloc_tos(), CH_UNIX
, CH_UTF16
,
47 substitute
, strlen(substitute
),
48 &subst_utf16
, &subst_len
)) {
51 if (!convert_string_talloc(talloc_tos(), CH_UNIX
, CH_UTF16
,
52 printname
, strlen(printname
),
53 &print_utf16
, &print_len
)) {
56 dst_len
= 20 + subst_len
+ print_len
;
57 dst
= talloc_array(mem_ctx
, uint8_t, dst_len
);
62 SIVAL(dst
, 0, IO_REPARSE_TAG_SYMLINK
); /* ReparseTag */
63 SSVAL(dst
, 4, 12 + subst_len
+ print_len
); /* ReparseDataLength */
64 SSVAL(dst
, 6, 0); /* Reserved */
65 SSVAL(dst
, 8, 0); /* SubstituteNameOffset */
66 SSVAL(dst
, 10, subst_len
); /* SubstituteNameLength */
67 SSVAL(dst
, 12, subst_len
); /* PrintNameOffset */
68 SSVAL(dst
, 14, print_len
); /* PrintNameLength */
69 SIVAL(dst
, 16, flags
); /* Flags */
71 if ((subst_utf16
!= NULL
) && (subst_len
!= 0)) {
72 memcpy(dst
+ 20, subst_utf16
, subst_len
);
73 TALLOC_FREE(subst_utf16
);
76 if ((print_utf16
!= NULL
) && (print_len
!= 0)) {
77 memcpy(dst
+ 20 + subst_len
, print_utf16
, print_len
);
78 TALLOC_FREE(print_utf16
);
85 TALLOC_FREE(subst_utf16
);
86 TALLOC_FREE(print_utf16
);
90 bool symlink_reparse_buffer_parse(
91 const uint8_t *src
, size_t srclen
, TALLOC_CTX
*mem_ctx
,
92 char **psubstitute_name
, char **pprint_name
, uint32_t *pflags
)
94 uint16_t reparse_data_length
;
95 uint16_t substitute_name_offset
, substitute_name_length
;
96 uint16_t print_name_offset
, print_name_length
;
98 char *substitute_name
= NULL
;
99 char *print_name
= NULL
;
102 DEBUG(10, ("srclen = %d, expected >= 20\n", (int)srclen
));
105 if (IVAL(src
, 0) != IO_REPARSE_TAG_SYMLINK
) {
106 DEBUG(10, ("Got ReparseTag %8.8x, expected %8.8x\n",
107 IVAL(src
, 0), IO_REPARSE_TAG_SYMLINK
));
111 reparse_data_length
= SVAL(src
, 4);
112 substitute_name_offset
= SVAL(src
, 8);
113 substitute_name_length
= SVAL(src
, 10);
114 print_name_offset
= SVAL(src
, 12);
115 print_name_length
= SVAL(src
, 14);
116 flags
= IVAL(src
, 16);
118 if (reparse_data_length
< 12) {
119 DEBUG(10, ("reparse_data_length = %d, expected >= 12\n",
120 (int)reparse_data_length
));
123 if (trans_oob(srclen
- 8, reparse_data_length
, 0)) {
124 DEBUG(10, ("reparse_data_length (%d) too large for "
125 "src_len (%d)\n", (int)reparse_data_length
,
129 if (trans_oob(reparse_data_length
- 12, substitute_name_offset
,
130 substitute_name_length
)) {
131 DEBUG(10, ("substitute_name (%d/%d) does not fit in "
132 "reparse_data_length (%d)\n",
133 (int)substitute_name_offset
,
134 (int)substitute_name_length
,
135 (int)reparse_data_length
- 12));
138 if (trans_oob(reparse_data_length
- 12, print_name_offset
,
139 print_name_length
)) {
140 DEBUG(10, ("print_name (%d/%d) does not fit in "
141 "reparse_data_length (%d)\n",
142 (int)print_name_offset
,
143 (int)print_name_length
,
144 (int)reparse_data_length
- 12));
148 if ((psubstitute_name
!= NULL
) &&
149 !convert_string_talloc(mem_ctx
, CH_UTF16
, CH_UNIX
,
150 src
+ 20 + substitute_name_offset
,
151 substitute_name_length
,
152 &substitute_name
, NULL
)) {
153 DEBUG(10, ("convert_string_talloc for substitute_name "
157 if ((pprint_name
!= NULL
) &&
158 !convert_string_talloc(mem_ctx
, CH_UTF16
, CH_UNIX
,
159 src
+ 20 + print_name_offset
,
161 &print_name
, NULL
)) {
162 DEBUG(10, ("convert_string_talloc for print_name "
164 TALLOC_FREE(substitute_name
);
167 if (psubstitute_name
!= NULL
) {
168 *psubstitute_name
= substitute_name
;
170 if (pprint_name
!= NULL
) {
171 *pprint_name
= print_name
;
173 if (pflags
!= NULL
) {