xref: /illumos-gate/usr/src/common/smbsrv/smb_door_legacy.c (revision b6805bf78d2bbbeeaea8909a05623587b42d58b3)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * Legacy encode/decode routines for door clients and servers.
28  */
29 
30 #ifndef _KERNEL
31 #include <errno.h>
32 #include <string.h>
33 #include <strings.h>
34 #else
35 #include <sys/types.h>
36 #include <sys/sunddi.h>
37 #include <sys/errno.h>
38 #endif
39 
40 #include <smbsrv/wintypes.h>
41 #include <smbsrv/smb_share.h>
42 #include <smbsrv/smb_door.h>
43 #include <smbsrv/alloc.h>
44 #include <smbsrv/smbinfo.h>
45 
46 smb_dr_ctx_t *
47 smb_dr_decode_start(char *ptr, int size)
48 {
49 	smb_dr_ctx_t *ctx = MEM_MALLOC("CommonDoor", sizeof (smb_dr_ctx_t));
50 	if (ctx) {
51 		ctx->start_ptr = ctx->ptr = ptr;
52 		ctx->end_ptr = ptr + size;
53 		ctx->status = 0;
54 	}
55 	return (ctx);
56 }
57 
58 int
59 smb_dr_decode_finish(smb_dr_ctx_t *ctx)
60 {
61 	int status = ctx->status;
62 	if (status == 0 && ctx->ptr != ctx->end_ptr)
63 		status = ENOTEMPTY;
64 
65 	MEM_FREE("CommonDoor", ctx);
66 	return (status);
67 }
68 
69 smb_dr_ctx_t *
70 smb_dr_encode_start(char *ptr, int size)
71 {
72 	smb_dr_ctx_t *ctx = MEM_MALLOC("CommonDoor",  sizeof (smb_dr_ctx_t));
73 	if (ctx) {
74 		ctx->start_ptr = ctx->ptr = ptr;
75 		ctx->end_ptr = ptr + size;
76 		ctx->status = 0;
77 	}
78 	return (ctx);
79 }
80 
81 int
82 smb_dr_encode_finish(smb_dr_ctx_t *ctx, unsigned int *used)
83 {
84 	int status = ctx->status;
85 	if (status == 0) {
86 		if (ctx->ptr < ctx->end_ptr) {
87 			/*LINTED E_PTRDIFF_OVERFLOW*/
88 			*used = ctx->ptr - ctx->start_ptr;
89 		} else {
90 			status = ENOSPC;
91 		}
92 	}
93 
94 	MEM_FREE("CommonDoor", ctx);
95 	return (status);
96 }
97 
98 DWORD
99 smb_dr_get_dword(smb_dr_ctx_t *ctx)
100 {
101 	DWORD num = 0;
102 	if (ctx->status == 0) {
103 		if (ctx->ptr + sizeof (DWORD) <= ctx->end_ptr) {
104 			(void) memcpy(&num, ctx->ptr, sizeof (DWORD));
105 			ctx->ptr += sizeof (DWORD);
106 		} else {
107 			ctx->status = ENOSPC;
108 		}
109 	}
110 	return (num);
111 }
112 
113 int32_t
114 smb_dr_get_int32(smb_dr_ctx_t *ctx)
115 {
116 	int32_t num = 0;
117 	if (ctx->status == 0) {
118 		if (ctx->ptr + sizeof (int32_t) <= ctx->end_ptr) {
119 			(void) memcpy(&num, ctx->ptr, sizeof (int32_t));
120 			ctx->ptr += sizeof (int32_t);
121 		} else {
122 			ctx->status = ENOSPC;
123 		}
124 	}
125 	return (num);
126 }
127 
128 uint32_t
129 smb_dr_get_uint32(smb_dr_ctx_t *ctx)
130 {
131 	return ((uint32_t)smb_dr_get_int32(ctx));
132 }
133 
134 char *
135 smb_dr_get_string(smb_dr_ctx_t *ctx)
136 {
137 	char *buf = NULL;
138 	int len = smb_dr_get_int32(ctx);
139 
140 	if (ctx->status == 0) {
141 		if (len == -1)
142 			return (buf);
143 
144 		if (ctx->ptr + len <= ctx->end_ptr) {
145 			buf = MEM_MALLOC("CommonDoor", len +1);
146 			if (buf) {
147 				if (len == 0) {
148 					(void) strcpy(buf, "");
149 				} else {
150 					(void) memcpy(buf, ctx->ptr, len);
151 					ctx->ptr += len;
152 					*(buf + len) = '\0';
153 				}
154 			} else {
155 #ifndef _KERNEL
156 				ctx->status = errno;
157 #else
158 				ctx->status = ENOMEM;
159 #endif
160 			}
161 		} else {
162 			ctx->status = ENOSPC;
163 		}
164 	}
165 	return (buf);
166 }
167 
168 void
169 smb_dr_put_dword(smb_dr_ctx_t *ctx, DWORD num)
170 {
171 	if (ctx->status == 0) {
172 		if (ctx->ptr + sizeof (DWORD) <= ctx->end_ptr) {
173 			(void) memcpy(ctx->ptr, &num, sizeof (DWORD));
174 			ctx->ptr += sizeof (DWORD);
175 		} else {
176 			ctx->status = ENOSPC;
177 		}
178 	}
179 }
180 
181 void
182 smb_dr_put_int32(smb_dr_ctx_t *ctx, int32_t num)
183 {
184 	if (ctx->status == 0) {
185 		if (ctx->ptr + sizeof (int32_t) <= ctx->end_ptr) {
186 			(void) memcpy(ctx->ptr, &num, sizeof (int32_t));
187 			ctx->ptr += sizeof (int32_t);
188 		} else {
189 			ctx->status = ENOSPC;
190 		}
191 	}
192 }
193 
194 void
195 smb_dr_put_uint32(smb_dr_ctx_t *ctx, uint32_t num)
196 {
197 	smb_dr_put_int32(ctx, (int32_t)num);
198 }
199 
200 void
201 smb_dr_put_string(smb_dr_ctx_t *ctx, const char *buf)
202 {
203 	int len;
204 
205 	if (!buf)
206 		len = -1;
207 	else
208 		len = strlen(buf);
209 
210 	if (ctx->status == 0) {
211 		smb_dr_put_int32(ctx, len);
212 		if (len <= 0)
213 			return;
214 
215 		if (ctx->ptr + len <= ctx->end_ptr) {
216 			(void) memcpy(ctx->ptr, buf, len);
217 			ctx->ptr += len;
218 		} else {
219 			ctx->status = ENOSPC;
220 		}
221 	}
222 }
223 
224 void
225 smb_dr_free_string(char *buf)
226 {
227 	if (buf)
228 		MEM_FREE("CommonDoor", buf);
229 }
230 
231 int64_t
232 smb_dr_get_int64(smb_dr_ctx_t *ctx)
233 {
234 	int64_t num = 0;
235 	if (ctx->status == 0) {
236 		if (ctx->ptr + sizeof (int64_t) <= ctx->end_ptr) {
237 			(void) memcpy(&num, ctx->ptr, sizeof (int64_t));
238 			ctx->ptr += sizeof (int64_t);
239 		} else {
240 			ctx->status = ENOSPC;
241 		}
242 	}
243 	return (num);
244 }
245 
246 uint64_t
247 smb_dr_get_uint64(smb_dr_ctx_t *ctx)
248 {
249 	return ((uint64_t)smb_dr_get_int64(ctx));
250 }
251 
252 
253 void
254 smb_dr_put_int64(smb_dr_ctx_t *ctx, int64_t num)
255 {
256 	if (ctx->status == 0) {
257 		if (ctx->ptr + sizeof (int64_t) <= ctx->end_ptr) {
258 			(void) memcpy(ctx->ptr, &num, sizeof (int64_t));
259 			ctx->ptr += sizeof (int64_t);
260 		} else {
261 			ctx->status = ENOSPC;
262 		}
263 	}
264 }
265 
266 void
267 smb_dr_put_uint64(smb_dr_ctx_t *ctx, uint64_t num)
268 {
269 	smb_dr_put_int64(ctx, (int64_t)num);
270 }
271 
272 void
273 smb_dr_put_short(smb_dr_ctx_t *ctx, short num)
274 {
275 	if (ctx->status == 0) {
276 		if (ctx->ptr + sizeof (short) <= ctx->end_ptr) {
277 			(void) memcpy(ctx->ptr, &num, sizeof (short));
278 			ctx->ptr += sizeof (short);
279 		} else {
280 			ctx->status = ENOSPC;
281 		}
282 	}
283 }
284 
285 short
286 smb_dr_get_short(smb_dr_ctx_t *ctx)
287 {
288 	short num = 0;
289 	if (ctx->status == 0) {
290 		if (ctx->ptr + sizeof (short) <= ctx->end_ptr) {
291 			(void) memcpy(&num, ctx->ptr, sizeof (short));
292 			ctx->ptr += sizeof (short);
293 		} else {
294 			ctx->status = ENOSPC;
295 		}
296 	}
297 	return (num);
298 }
299 
300 void
301 smb_dr_put_ushort(smb_dr_ctx_t *ctx, unsigned short num)
302 {
303 	smb_dr_put_short(ctx, (short)num);
304 }
305 
306 unsigned short
307 smb_dr_get_ushort(smb_dr_ctx_t *ctx)
308 {
309 	return ((unsigned short)smb_dr_get_short(ctx));
310 }
311 
312 void
313 smb_dr_put_word(smb_dr_ctx_t *ctx, WORD num)
314 {
315 	smb_dr_put_ushort(ctx, num);
316 }
317 
318 WORD
319 smb_dr_get_word(smb_dr_ctx_t *ctx)
320 {
321 	return (smb_dr_get_ushort(ctx));
322 }
323 
324 void
325 smb_dr_put_BYTE(smb_dr_ctx_t *ctx, BYTE byte)
326 {
327 	if (ctx->status == 0) {
328 		if (ctx->ptr + sizeof (BYTE) <= ctx->end_ptr) {
329 			(void) memcpy(ctx->ptr, &byte, sizeof (BYTE));
330 			ctx->ptr += sizeof (BYTE);
331 		} else {
332 			ctx->status = ENOSPC;
333 		}
334 	}
335 }
336 
337 BYTE
338 smb_dr_get_BYTE(smb_dr_ctx_t *ctx)
339 {
340 	BYTE byte = 0;
341 	if (ctx->status == 0) {
342 		if (ctx->ptr + sizeof (BYTE) <= ctx->end_ptr) {
343 			(void) memcpy(&byte, ctx->ptr, sizeof (BYTE));
344 			ctx->ptr += sizeof (BYTE);
345 		} else {
346 			ctx->status = ENOSPC;
347 		}
348 	}
349 	return (byte);
350 }
351 
352 void
353 smb_dr_put_buf(smb_dr_ctx_t *ctx, unsigned char *start, int len)
354 {
355 	smb_dr_put_int32(ctx, len);
356 	if (ctx->status == 0) {
357 		if (ctx->ptr + len <= ctx->end_ptr) {
358 			(void) memcpy(ctx->ptr, start, len);
359 			ctx->ptr += len;
360 		} else {
361 			ctx->status = ENOSPC;
362 		}
363 	}
364 }
365 
366 int
367 smb_dr_get_buf(smb_dr_ctx_t *ctx, unsigned char *buf, int bufsize)
368 {
369 	int len = -1;
370 
371 	if (!buf)
372 		return (-1);
373 
374 	len = smb_dr_get_int32(ctx);
375 	if (ctx->status == 0) {
376 		if (bufsize < len) {
377 			ctx->status = ENOSPC;
378 			return (-2);
379 		}
380 
381 		if (ctx->ptr + len <= ctx->end_ptr) {
382 			(void) memcpy(buf, ctx->ptr, len);
383 			ctx->ptr += len;
384 		} else {
385 			ctx->status = ENOSPC;
386 			return (-3);
387 		}
388 	}
389 
390 	return (len);
391 }
392 
393 void
394 smb_dr_get_share(smb_dr_ctx_t *ctx, smb_share_t *si)
395 {
396 	if (ctx->status == 0) {
397 		if (smb_dr_get_int32(ctx)) {
398 			(void) memcpy(si, ctx->ptr, sizeof (smb_share_t));
399 			ctx->ptr += sizeof (smb_share_t);
400 		} else {
401 			bzero(si, sizeof (smb_share_t));
402 		}
403 	} else {
404 		bzero(si, sizeof (smb_share_t));
405 	}
406 }
407 
408 void
409 smb_dr_put_share(smb_dr_ctx_t *ctx, smb_share_t *si)
410 {
411 	if (si) {
412 		smb_dr_put_int32(ctx, 1);
413 		if (ctx->ptr + sizeof (smb_share_t) <= ctx->end_ptr) {
414 			(void) memcpy(ctx->ptr, si, sizeof (smb_share_t));
415 			ctx->ptr += sizeof (smb_share_t);
416 		} else {
417 			ctx->status = ENOSPC;
418 		}
419 	} else {
420 		smb_dr_put_int32(ctx, 0);
421 	}
422 }
423