xref: /illumos-gate/usr/src/common/smbsrv/smb_door_legacy.c (revision c8ec8eea9849cac239663c46be8a7f5d2ba7ca00)
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 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"@(#)smb_common_door_decode.c	1.2	08/08/07 SMI"
27 
28 /*
29  * Provides encode/decode routines for all door servers/clients.
30  */
31 
32 #ifdef _KERNEL
33 #include <sys/types.h>
34 #include <sys/sunddi.h>
35 #else
36 #include <string.h>
37 #endif
38 #include <sys/errno.h>
39 #ifndef _KERNEL
40 #include <errno.h>
41 #endif
42 
43 #include <smbsrv/alloc.h>
44 #include <smbsrv/smb_common_door.h>
45 #include <smbsrv/wintypes.h>
46 
47 
48 smb_dr_ctx_t *
49 smb_dr_decode_start(char *ptr, int size)
50 {
51 	smb_dr_ctx_t *ctx = MEM_MALLOC("CommonDoor", sizeof (smb_dr_ctx_t));
52 	if (ctx) {
53 		ctx->start_ptr = ctx->ptr = ptr;
54 		ctx->end_ptr = ptr + size;
55 		ctx->status = 0;
56 	}
57 	return (ctx);
58 }
59 
60 int
61 smb_dr_decode_finish(smb_dr_ctx_t *ctx)
62 {
63 	int status = ctx->status;
64 	if (status == 0 && ctx->ptr != ctx->end_ptr) {
65 		status = ENOTEMPTY;
66 	}
67 	MEM_FREE("CommonDoor", ctx);
68 	return (status);
69 }
70 
71 smb_dr_ctx_t *
72 smb_dr_encode_start(char *ptr, int size)
73 {
74 	smb_dr_ctx_t *ctx = MEM_MALLOC("CommonDoor",  sizeof (smb_dr_ctx_t));
75 	if (ctx) {
76 		ctx->start_ptr = ctx->ptr = ptr;
77 		ctx->end_ptr = ptr + size;
78 		ctx->status = 0;
79 	}
80 	return (ctx);
81 }
82 
83 int
84 smb_dr_encode_finish(smb_dr_ctx_t *ctx, unsigned int *used)
85 {
86 	int status = ctx->status;
87 	if (status == 0) {
88 		if (ctx->ptr < ctx->end_ptr) {
89 			/*LINTED E_PTRDIFF_OVERFLOW*/
90 			*used = ctx->ptr - ctx->start_ptr;
91 		}
92 		else
93 			status = ENOSPC;
94 	}
95 
96 	MEM_FREE("CommonDoor", ctx);
97 	return (status);
98 }
99 
100 DWORD
101 smb_dr_get_dword(smb_dr_ctx_t *ctx)
102 {
103 	DWORD num = 0;
104 	if (ctx->status == 0) {
105 		if (ctx->ptr + sizeof (DWORD) <= ctx->end_ptr) {
106 			(void) memcpy(&num, ctx->ptr, sizeof (DWORD));
107 			ctx->ptr += sizeof (DWORD);
108 		}
109 		else
110 			ctx->status = ENOSPC;
111 	}
112 	return (num);
113 }
114 
115 int32_t
116 smb_dr_get_int32(smb_dr_ctx_t *ctx)
117 {
118 	int32_t num = 0;
119 	if (ctx->status == 0) {
120 		if (ctx->ptr + sizeof (int32_t) <= ctx->end_ptr) {
121 			(void) memcpy(&num, ctx->ptr, sizeof (int32_t));
122 			ctx->ptr += sizeof (int32_t);
123 		}
124 		else
125 			ctx->status = ENOSPC;
126 	}
127 	return (num);
128 }
129 
130 uint32_t
131 smb_dr_get_uint32(smb_dr_ctx_t *ctx)
132 {
133 	return ((uint32_t)smb_dr_get_int32(ctx));
134 }
135 
136 char *
137 smb_dr_get_string(smb_dr_ctx_t *ctx)
138 {
139 	char *buf = NULL;
140 	int len = smb_dr_get_int32(ctx);
141 
142 	if (ctx->status == 0) {
143 		if (len == -1)
144 			return (buf);
145 
146 		if (ctx->ptr + len <= ctx->end_ptr) {
147 			buf = MEM_MALLOC("CommonDoor", len +1);
148 			if (buf) {
149 				if (len == 0)
150 					(void) strcpy(buf, "");
151 				else {
152 					(void) memcpy(buf, ctx->ptr, len);
153 					ctx->ptr += len;
154 					*(buf + len) = '\0';
155 				}
156 			}
157 			else
158 #ifndef _KERNEL
159 				ctx->status = errno;
160 #else
161 				ctx->status = ENOMEM;
162 #endif
163 		}
164 		else
165 			ctx->status = ENOSPC;
166 	}
167 	return (buf);
168 }
169 
170 void
171 smb_dr_put_dword(smb_dr_ctx_t *ctx, DWORD num)
172 {
173 	if (ctx->status == 0) {
174 		if (ctx->ptr + sizeof (DWORD) <= ctx->end_ptr) {
175 			(void) memcpy(ctx->ptr, &num, sizeof (DWORD));
176 			ctx->ptr += sizeof (DWORD);
177 		} else
178 			ctx->status = ENOSPC;
179 	}
180 }
181 
182 void
183 smb_dr_put_int32(smb_dr_ctx_t *ctx, int32_t num)
184 {
185 	if (ctx->status == 0) {
186 		if (ctx->ptr + sizeof (int32_t) <= ctx->end_ptr) {
187 			(void) memcpy(ctx->ptr, &num, sizeof (int32_t));
188 			ctx->ptr += sizeof (int32_t);
189 		} else
190 			ctx->status = ENOSPC;
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 		}
219 		else
220 			ctx->status = ENOSPC;
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 		}
240 		else
241 			ctx->status = ENOSPC;
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 void
266 smb_dr_put_uint64(smb_dr_ctx_t *ctx, uint64_t num)
267 {
268 	smb_dr_put_int64(ctx, (int64_t)num);
269 }
270 
271 void
272 smb_dr_put_short(smb_dr_ctx_t *ctx, short num)
273 {
274 	if (ctx->status == 0) {
275 		if (ctx->ptr + sizeof (short) <= ctx->end_ptr) {
276 			(void) memcpy(ctx->ptr, &num, sizeof (short));
277 			ctx->ptr += sizeof (short);
278 		} else
279 			ctx->status = ENOSPC;
280 	}
281 }
282 
283 short
284 smb_dr_get_short(smb_dr_ctx_t *ctx)
285 {
286 	short num = 0;
287 	if (ctx->status == 0) {
288 		if (ctx->ptr + sizeof (short) <= ctx->end_ptr) {
289 			(void) memcpy(&num, ctx->ptr, sizeof (short));
290 			ctx->ptr += sizeof (short);
291 		}
292 		else
293 			ctx->status = ENOSPC;
294 	}
295 	return (num);
296 }
297 
298 void
299 smb_dr_put_ushort(smb_dr_ctx_t *ctx, unsigned short num)
300 {
301 	smb_dr_put_short(ctx, (short)num);
302 }
303 
304 unsigned short
305 smb_dr_get_ushort(smb_dr_ctx_t *ctx)
306 {
307 	return ((unsigned short)smb_dr_get_short(ctx));
308 }
309 
310 void
311 smb_dr_put_word(smb_dr_ctx_t *ctx, WORD num)
312 {
313 	smb_dr_put_ushort(ctx, num);
314 }
315 
316 WORD
317 smb_dr_get_word(smb_dr_ctx_t *ctx)
318 {
319 	return (smb_dr_get_ushort(ctx));
320 }
321 
322 void
323 smb_dr_put_BYTE(smb_dr_ctx_t *ctx, BYTE byte)
324 {
325 	if (ctx->status == 0) {
326 		if (ctx->ptr + sizeof (BYTE) <= ctx->end_ptr) {
327 			(void) memcpy(ctx->ptr, &byte, sizeof (BYTE));
328 			ctx->ptr += sizeof (BYTE);
329 		} else
330 			ctx->status = ENOSPC;
331 	}
332 }
333 
334 BYTE
335 smb_dr_get_BYTE(smb_dr_ctx_t *ctx)
336 {
337 	BYTE byte = 0;
338 	if (ctx->status == 0) {
339 		if (ctx->ptr + sizeof (BYTE) <= ctx->end_ptr) {
340 			(void) memcpy(&byte, ctx->ptr, sizeof (BYTE));
341 			ctx->ptr += sizeof (BYTE);
342 		}
343 		else
344 			ctx->status = ENOSPC;
345 	}
346 	return (byte);
347 }
348 
349 void
350 smb_dr_put_buf(smb_dr_ctx_t *ctx, unsigned char *start, int len)
351 {
352 	smb_dr_put_int32(ctx, len);
353 	if (ctx->status == 0) {
354 		if (ctx->ptr + len <= ctx->end_ptr) {
355 			(void) memcpy(ctx->ptr, start, len);
356 			ctx->ptr += len;
357 		} else
358 			ctx->status = ENOSPC;
359 	}
360 }
361 
362 int
363 smb_dr_get_buf(smb_dr_ctx_t *ctx, unsigned char *buf, int bufsize)
364 {
365 	int len = -1;
366 
367 	if (!buf)
368 		return (-1);
369 
370 	len = smb_dr_get_int32(ctx);
371 	if (ctx->status == 0) {
372 		if (bufsize < len) {
373 			ctx->status = ENOSPC;
374 			return (-2);
375 		}
376 
377 		if (ctx->ptr + len <= ctx->end_ptr) {
378 			(void) memcpy(buf, ctx->ptr, len);
379 			ctx->ptr += len;
380 		} else {
381 			ctx->status = ENOSPC;
382 			return (-3);
383 		}
384 	}
385 
386 	return (len);
387 }
388