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