Home | History | Annotate | Download | only in smbsrv
      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 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #include <sys/sunddi.h>
     27 #ifndef _KERNEL
     28 #include <string.h>
     29 #include <strings.h>
     30 #endif /* _KERNEL */
     31 #include <smbsrv/smb_xdr.h>
     32 #include <sys/socket.h>
     33 
     34 bool_t
     35 xdr_smb_dr_string_t(xdrs, objp)
     36 	XDR *xdrs;
     37 	smb_dr_string_t *objp;
     38 {
     39 	if (!xdr_string(xdrs, &objp->buf, ~0))
     40 		return (FALSE);
     41 	return (TRUE);
     42 }
     43 
     44 bool_t
     45 xdr_smb_dr_bytes_t(xdrs, objp)
     46 	XDR *xdrs;
     47 	smb_dr_bytes_t *objp;
     48 {
     49 	if (!xdr_array(xdrs, (char **)&objp->bytes_val,
     50 	    (uint32_t *)&objp->bytes_len, ~0, sizeof (uint8_t),
     51 	    (xdrproc_t)xdr_uint8_t))
     52 		return (FALSE);
     53 	return (TRUE);
     54 }
     55 
     56 /*
     57  * Encode an opipe header structure into a buffer.
     58  */
     59 int
     60 smb_opipe_hdr_encode(smb_opipe_hdr_t *hdr, uint8_t *buf, uint32_t buflen)
     61 {
     62 	XDR xdrs;
     63 	int rc = 0;
     64 
     65 	xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_ENCODE);
     66 
     67 	if (!smb_opipe_hdr_xdr(&xdrs, hdr))
     68 		rc = -1;
     69 
     70 	xdr_destroy(&xdrs);
     71 	return (rc);
     72 }
     73 
     74 /*
     75  * Decode an XDR buffer into an opipe header structure.
     76  */
     77 int
     78 smb_opipe_hdr_decode(smb_opipe_hdr_t *hdr, uint8_t *buf, uint32_t buflen)
     79 {
     80 	XDR xdrs;
     81 	int rc = 0;
     82 
     83 	bzero(hdr, sizeof (smb_opipe_hdr_t));
     84 	xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_DECODE);
     85 
     86 	if (!smb_opipe_hdr_xdr(&xdrs, hdr))
     87 		rc = -1;
     88 
     89 	xdr_destroy(&xdrs);
     90 	return (rc);
     91 }
     92 
     93 bool_t
     94 smb_opipe_hdr_xdr(XDR *xdrs, smb_opipe_hdr_t *objp)
     95 {
     96 	if (!xdr_uint32_t(xdrs, &objp->oh_magic))
     97 		return (FALSE);
     98 	if (!xdr_uint32_t(xdrs, &objp->oh_fid))
     99 		return (FALSE);
    100 	if (!xdr_uint32_t(xdrs, &objp->oh_op))
    101 		return (FALSE);
    102 	if (!xdr_uint32_t(xdrs, &objp->oh_datalen))
    103 		return (FALSE);
    104 	if (!xdr_uint32_t(xdrs, &objp->oh_resid))
    105 		return (FALSE);
    106 	if (!xdr_uint32_t(xdrs, &objp->oh_status))
    107 		return (FALSE);
    108 	return (TRUE);
    109 }
    110 
    111 /*
    112  * Encode an smb_netuserinfo_t into a buffer.
    113  */
    114 int
    115 smb_netuserinfo_encode(smb_netuserinfo_t *info, uint8_t *buf,
    116     uint32_t buflen, uint_t *nbytes)
    117 {
    118 	XDR xdrs;
    119 	int rc = 0;
    120 
    121 	xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_ENCODE);
    122 
    123 	if (!smb_netuserinfo_xdr(&xdrs, info))
    124 		rc = -1;
    125 
    126 	if (nbytes != NULL)
    127 		*nbytes = xdr_getpos(&xdrs);
    128 	xdr_destroy(&xdrs);
    129 	return (rc);
    130 }
    131 
    132 /*
    133  * Decode an XDR buffer into an smb_netuserinfo_t.
    134  */
    135 int
    136 smb_netuserinfo_decode(smb_netuserinfo_t *info, uint8_t *buf,
    137     uint32_t buflen, uint_t *nbytes)
    138 {
    139 	XDR xdrs;
    140 	int rc = 0;
    141 
    142 	xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_DECODE);
    143 
    144 	bzero(info, sizeof (smb_netuserinfo_t));
    145 	if (!smb_netuserinfo_xdr(&xdrs, info))
    146 		rc = -1;
    147 
    148 	if (nbytes != NULL)
    149 		*nbytes = xdr_getpos(&xdrs);
    150 	xdr_destroy(&xdrs);
    151 	return (rc);
    152 }
    153 
    154 bool_t
    155 xdr_smb_inaddr_t(XDR *xdrs, smb_inaddr_t *objp)
    156 {
    157 	if (!xdr_int32_t(xdrs, &objp->a_family))
    158 		return (FALSE);
    159 	if (objp->a_family == AF_INET) {
    160 		if (!xdr_uint32_t(xdrs, (in_addr_t *)&objp->a_ipv4))
    161 			return (FALSE);
    162 	} else {
    163 		if (!xdr_vector(xdrs, (char *)&objp->a_ipv6,
    164 		    sizeof (objp->a_ipv6), sizeof (char), (xdrproc_t)xdr_char))
    165 			return (FALSE);
    166 	}
    167 	return (TRUE);
    168 }
    169 
    170 /*
    171  * XDR encode/decode for smb_netuserinfo_t.
    172  */
    173 bool_t
    174 smb_netuserinfo_xdr(XDR *xdrs, smb_netuserinfo_t *objp)
    175 {
    176 	if (!xdr_uint64_t(xdrs, &objp->ui_session_id))
    177 		return (FALSE);
    178 	if (!xdr_uint16_t(xdrs, &objp->ui_uid))
    179 		return (FALSE);
    180 	if (!xdr_uint16_t(xdrs, &objp->ui_domain_len))
    181 		return (FALSE);
    182 	if (!xdr_string(xdrs, &objp->ui_domain, ~0))
    183 		return (FALSE);
    184 	if (!xdr_uint16_t(xdrs, &objp->ui_account_len))
    185 		return (FALSE);
    186 	if (!xdr_string(xdrs, &objp->ui_account, ~0))
    187 		return (FALSE);
    188 	if (!xdr_uint16_t(xdrs, &objp->ui_workstation_len))
    189 		return (FALSE);
    190 	if (!xdr_string(xdrs, &objp->ui_workstation, ~0))
    191 		return (FALSE);
    192 	if (!xdr_smb_inaddr_t(xdrs, &objp->ui_ipaddr))
    193 		return (FALSE);
    194 	if (!xdr_int32_t(xdrs, &objp->ui_native_os))
    195 		return (FALSE);
    196 	if (!xdr_int64_t(xdrs, &objp->ui_logon_time))
    197 		return (FALSE);
    198 	if (!xdr_uint32_t(xdrs, &objp->ui_numopens))
    199 		return (FALSE);
    200 	if (!xdr_uint32_t(xdrs, &objp->ui_flags))
    201 		return (FALSE);
    202 	return (TRUE);
    203 }
    204 
    205 /*
    206  * Encode an smb_netconnectinfo_t into a buffer.
    207  */
    208 int
    209 smb_netconnectinfo_encode(smb_netconnectinfo_t *info, uint8_t *buf,
    210     uint32_t buflen, uint_t *nbytes)
    211 {
    212 	XDR xdrs;
    213 	int rc = 0;
    214 
    215 	xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_ENCODE);
    216 
    217 	if (!smb_netconnectinfo_xdr(&xdrs, info))
    218 		rc = -1;
    219 
    220 	if (nbytes != NULL)
    221 		*nbytes = xdr_getpos(&xdrs);
    222 	xdr_destroy(&xdrs);
    223 	return (rc);
    224 }
    225 
    226 /*
    227  * Decode an XDR buffer into an smb_netconnectinfo_t.
    228  */
    229 int
    230 smb_netconnectinfo_decode(smb_netconnectinfo_t *info, uint8_t *buf,
    231     uint32_t buflen, uint_t *nbytes)
    232 {
    233 	XDR xdrs;
    234 	int rc = 0;
    235 
    236 	xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_DECODE);
    237 
    238 	bzero(info, sizeof (smb_netconnectinfo_t));
    239 	if (!smb_netconnectinfo_xdr(&xdrs, info))
    240 		rc = -1;
    241 
    242 	if (nbytes != NULL)
    243 		*nbytes = xdr_getpos(&xdrs);
    244 	xdr_destroy(&xdrs);
    245 	return (rc);
    246 }
    247 
    248 /*
    249  * XDR encode/decode for smb_netconnectinfo_t.
    250  */
    251 bool_t
    252 smb_netconnectinfo_xdr(XDR *xdrs, smb_netconnectinfo_t *objp)
    253 {
    254 	if (!xdr_uint32_t(xdrs, &objp->ci_id))
    255 		return (FALSE);
    256 	if (!xdr_uint32_t(xdrs, &objp->ci_type))
    257 		return (FALSE);
    258 	if (!xdr_uint32_t(xdrs, &objp->ci_numopens))
    259 		return (FALSE);
    260 	if (!xdr_uint32_t(xdrs, &objp->ci_numusers))
    261 		return (FALSE);
    262 	if (!xdr_uint32_t(xdrs, &objp->ci_time))
    263 		return (FALSE);
    264 	if (!xdr_uint32_t(xdrs, &objp->ci_namelen))
    265 		return (FALSE);
    266 	if (!xdr_uint32_t(xdrs, &objp->ci_sharelen))
    267 		return (FALSE);
    268 	if (!xdr_string(xdrs, &objp->ci_username, MAXNAMELEN))
    269 		return (FALSE);
    270 	if (!xdr_string(xdrs, &objp->ci_share, MAXNAMELEN))
    271 		return (FALSE);
    272 	return (TRUE);
    273 }
    274 
    275 /*
    276  * Encode an smb_netfileinfo_t into a buffer.
    277  */
    278 int
    279 smb_netfileinfo_encode(smb_netfileinfo_t *info, uint8_t *buf,
    280     uint32_t buflen, uint_t *nbytes)
    281 {
    282 	XDR xdrs;
    283 	int rc = 0;
    284 
    285 	xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_ENCODE);
    286 
    287 	if (!smb_netfileinfo_xdr(&xdrs, info))
    288 		rc = -1;
    289 
    290 	if (nbytes != NULL)
    291 		*nbytes = xdr_getpos(&xdrs);
    292 	xdr_destroy(&xdrs);
    293 	return (rc);
    294 }
    295 
    296 /*
    297  * Decode an XDR buffer into an smb_netfileinfo_t.
    298  */
    299 int
    300 smb_netfileinfo_decode(smb_netfileinfo_t *info, uint8_t *buf,
    301     uint32_t buflen, uint_t *nbytes)
    302 {
    303 	XDR xdrs;
    304 	int rc = 0;
    305 
    306 	xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_DECODE);
    307 
    308 	bzero(info, sizeof (smb_netfileinfo_t));
    309 	if (!smb_netfileinfo_xdr(&xdrs, info))
    310 		rc = -1;
    311 
    312 	if (nbytes != NULL)
    313 		*nbytes = xdr_getpos(&xdrs);
    314 	xdr_destroy(&xdrs);
    315 	return (rc);
    316 }
    317 
    318 /*
    319  * XDR encode/decode for smb_netfileinfo_t.
    320  */
    321 bool_t
    322 smb_netfileinfo_xdr(XDR *xdrs, smb_netfileinfo_t *objp)
    323 {
    324 	if (!xdr_uint16_t(xdrs, &objp->fi_fid))
    325 		return (FALSE);
    326 	if (!xdr_uint32_t(xdrs, &objp->fi_uniqid))
    327 		return (FALSE);
    328 	if (!xdr_uint32_t(xdrs, &objp->fi_permissions))
    329 		return (FALSE);
    330 	if (!xdr_uint32_t(xdrs, &objp->fi_numlocks))
    331 		return (FALSE);
    332 	if (!xdr_uint32_t(xdrs, &objp->fi_pathlen))
    333 		return (FALSE);
    334 	if (!xdr_uint32_t(xdrs, &objp->fi_namelen))
    335 		return (FALSE);
    336 	if (!xdr_string(xdrs, &objp->fi_path, MAXPATHLEN))
    337 		return (FALSE);
    338 	if (!xdr_string(xdrs, &objp->fi_username, MAXNAMELEN))
    339 		return (FALSE);
    340 	return (TRUE);
    341 }
    342 
    343 bool_t
    344 xdr_smb_dr_kshare_t(xdrs, objp)
    345 	XDR *xdrs;
    346 	smb_dr_kshare_t *objp;
    347 {
    348 	if (!xdr_int32_t(xdrs, &objp->k_op))
    349 		return (FALSE);
    350 	if (!xdr_string(xdrs, &objp->k_path, MAXPATHLEN))
    351 		return (FALSE);
    352 	if (!xdr_string(xdrs, &objp->k_sharename, MAXNAMELEN))
    353 		return (FALSE);
    354 	return (TRUE);
    355 }
    356 
    357 bool_t
    358 xdr_smb_dr_get_gmttokens_t(XDR *xdrs, smb_dr_get_gmttokens_t *objp)
    359 {
    360 	if (!xdr_uint32_t(xdrs, &objp->gg_count)) {
    361 		return (FALSE);
    362 	}
    363 	if (!xdr_string(xdrs, &objp->gg_path, ~0)) {
    364 		return (FALSE);
    365 	}
    366 	return (TRUE);
    367 }
    368 
    369 bool_t
    370 xdr_gmttoken(XDR *xdrs, gmttoken *objp)
    371 {
    372 	if (!xdr_string(xdrs, objp, SMB_VSS_GMT_SIZE)) {
    373 		return (FALSE);
    374 	}
    375 	return (TRUE);
    376 }
    377 
    378 bool_t
    379 xdr_smb_dr_return_gmttokens_t(XDR *xdrs, smb_dr_return_gmttokens_t *objp)
    380 {
    381 	if (!xdr_uint32_t(xdrs, &objp->rg_count)) {
    382 		return (FALSE);
    383 	}
    384 	if (!xdr_array(xdrs, (char **)&objp->rg_gmttokens.rg_gmttokens_val,
    385 	    (uint_t *)&objp->rg_gmttokens.rg_gmttokens_len, ~0,
    386 	    sizeof (gmttoken), (xdrproc_t)xdr_gmttoken)) {
    387 		return (FALSE);
    388 	}
    389 	return (TRUE);
    390 }
    391 
    392 bool_t
    393 xdr_smb_dr_map_gmttoken_t(XDR *xdrs, smb_dr_map_gmttoken_t *objp)
    394 {
    395 	if (!xdr_string(xdrs, &objp->mg_path, MAXPATHLEN)) {
    396 		return (FALSE);
    397 	}
    398 	if (!xdr_string(xdrs, &objp->mg_gmttoken, SMB_VSS_GMT_SIZE)) {
    399 		return (FALSE);
    400 	}
    401 	return (TRUE);
    402 }
    403