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 #include <stdlib.h> 27 #include <strings.h> 28 #include <rpc/xdr.h> 29 #include <errno.h> 30 #include <syslog.h> 31 #include <smbsrv/libsmb.h> 32 #include <smbsrv/smb_xdr.h> 33 #include <smbsrv/smb_door.h> 34 35 36 /* 37 * Generic XDR encoder. 38 * 39 * Returns a malloc'd, encoded buffer upon success. 40 * Otherwise, returns NULL. 41 */ 42 char * 43 smb_common_encode(void *data, xdrproc_t proc, size_t *rsize) 44 { 45 XDR xdrs; 46 char *buf; 47 size_t len; 48 49 if (proc == NULL || data == NULL || rsize == NULL) { 50 syslog(LOG_ERR, "smb_common_encode: invalid parameter"); 51 return (NULL); 52 } 53 54 len = xdr_sizeof(proc, data); 55 56 if ((buf = malloc(len)) == NULL) { 57 syslog(LOG_ERR, "smb_common_encode: %m"); 58 *rsize = 0; 59 return (NULL); 60 } 61 62 xdrmem_create(&xdrs, buf, len, XDR_ENCODE); 63 *rsize = len; 64 65 if (!proc(&xdrs, data)) { 66 syslog(LOG_DEBUG, "smb_common_encode: encode error"); 67 free(buf); 68 buf = NULL; 69 *rsize = 0; 70 } 71 72 xdr_destroy(&xdrs); 73 return (buf); 74 } 75 76 /* 77 * Generic XDR decoder. Ensure that data is non-null and bzero'd. 78 */ 79 int 80 smb_common_decode(char *buf, size_t len, xdrproc_t proc, void *data) 81 { 82 XDR xdrs; 83 int rc = 0; 84 85 if (data == NULL) 86 return (-1); 87 88 xdrmem_create(&xdrs, buf, len, XDR_DECODE); 89 if (!proc(&xdrs, data)) 90 rc = -1; 91 92 xdr_destroy(&xdrs); 93 return (rc); 94 } 95 96 /* 97 * smb_kshare_mkselfrel 98 * 99 * encode: structure -> flat buffer (buffer size) 100 * Pre-condition: kshare is non-null. 101 */ 102 uint8_t * 103 smb_kshare_mkselfrel(smb_dr_kshare_t *kshare, uint32_t *len) 104 { 105 uint8_t *buf; 106 XDR xdrs; 107 108 if (!kshare) 109 return (NULL); 110 111 *len = xdr_sizeof(smb_dr_kshare_xdr, kshare); 112 buf = (uint8_t *)malloc(*len); 113 if (!buf) 114 return (NULL); 115 116 xdrmem_create(&xdrs, (const caddr_t)buf, *len, XDR_ENCODE); 117 118 if (!smb_dr_kshare_xdr(&xdrs, kshare)) { 119 *len = 0; 120 free(buf); 121 buf = NULL; 122 } 123 124 xdr_destroy(&xdrs); 125 return (buf); 126 } 127 128 char * 129 smb_string_encode(char *s, size_t *rsize) 130 { 131 smb_string_t obj; 132 XDR xdrs; 133 char *buf = NULL; 134 size_t len; 135 136 if ((obj.buf = s) == NULL) { 137 syslog(LOG_DEBUG, "smb_string_encode: invalid param"); 138 goto smb_string_encode_failed; 139 } 140 141 len = xdr_sizeof(smb_string_xdr, &obj); 142 if ((buf = calloc(len, 1)) == NULL) { 143 syslog(LOG_DEBUG, "smb_string_encode: %m"); 144 goto smb_string_encode_failed; 145 } 146 147 xdrmem_create(&xdrs, buf, len, XDR_ENCODE); 148 149 if (!smb_string_xdr(&xdrs, &obj)) { 150 syslog(LOG_DEBUG, "smb_string_encode: encode failed"); 151 xdr_destroy(&xdrs); 152 free(buf); 153 goto smb_string_encode_failed; 154 } 155 156 xdr_destroy(&xdrs); 157 if (rsize) 158 *rsize = len; 159 return (buf); 160 161 smb_string_encode_failed: 162 if (rsize) 163 *rsize = 0; 164 return (NULL); 165 } 166 167 int 168 smb_string_decode(smb_string_t *obj, char *buf, size_t buflen) 169 { 170 XDR xdrs; 171 int rc = 0; 172 173 xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_DECODE); 174 175 bzero(obj, sizeof (smb_string_t)); 176 if (!smb_string_xdr(&xdrs, obj)) 177 rc = -1; 178 179 xdr_destroy(&xdrs); 180 return (rc); 181 } 182 183 /* 184 * Encode an lsa_account_t into a buffer. 185 */ 186 int 187 lsa_account_encode(lsa_account_t *acct, uint8_t *buf, uint32_t buflen) 188 { 189 XDR xdrs; 190 int rc = 0; 191 192 xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_ENCODE); 193 194 if (!lsa_account_xdr(&xdrs, acct)) 195 rc = -1; 196 197 xdr_destroy(&xdrs); 198 return (rc); 199 } 200 201 /* 202 * Decode an XDR buffer into an lsa_account_t. 203 */ 204 int 205 lsa_account_decode(lsa_account_t *acct, uint8_t *buf, uint32_t buflen) 206 { 207 XDR xdrs; 208 int rc = 0; 209 210 xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_DECODE); 211 212 bzero(acct, sizeof (lsa_account_t)); 213 if (!lsa_account_xdr(&xdrs, acct)) 214 rc = -1; 215 216 xdr_destroy(&xdrs); 217 return (rc); 218 } 219 220 bool_t 221 lsa_account_xdr(XDR *xdrs, lsa_account_t *objp) 222 { 223 if (!xdr_uint16_t(xdrs, &objp->a_sidtype)) 224 return (FALSE); 225 if (!xdr_uint32_t(xdrs, &objp->a_status)) 226 return (FALSE); 227 if (!xdr_vector(xdrs, (char *)objp->a_domain, MAXNAMELEN, 228 sizeof (char), (xdrproc_t)xdr_char)) 229 return (FALSE); 230 if (!xdr_vector(xdrs, (char *)objp->a_name, MAXNAMELEN, 231 sizeof (char), (xdrproc_t)xdr_char)) 232 return (FALSE); 233 if (!xdr_vector(xdrs, (char *)objp->a_sid, SMB_SID_STRSZ, 234 sizeof (char), (xdrproc_t)xdr_char)) 235 return (FALSE); 236 return (TRUE); 237 } 238