15331Samw /*
25331Samw * CDDL HEADER START
35331Samw *
45331Samw * The contents of this file are subject to the terms of the
55331Samw * Common Development and Distribution License (the "License").
65331Samw * You may not use this file except in compliance with the License.
75331Samw *
85331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95331Samw * or http://www.opensolaris.org/os/licensing.
105331Samw * See the License for the specific language governing permissions
115331Samw * and limitations under the License.
125331Samw *
135331Samw * When distributing Covered Code, include this CDDL HEADER in each
145331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155331Samw * If applicable, add the following below this CDDL HEADER, with the
165331Samw * fields enclosed by brackets "[]" replaced with your own identifying
175331Samw * information: Portions Copyright [yyyy] [name of copyright owner]
185331Samw *
195331Samw * CDDL HEADER END
205331Samw */
215331Samw /*
22*12508Samw@Sun.COM * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
235331Samw */
245331Samw
255331Samw #include <stdlib.h>
265331Samw #include <strings.h>
275331Samw #include <rpc/xdr.h>
285331Samw #include <errno.h>
2911963SAfshin.Ardakani@Sun.COM #include <syslog.h>
305331Samw #include <smbsrv/libsmb.h>
315331Samw #include <smbsrv/smb_xdr.h>
3211963SAfshin.Ardakani@Sun.COM #include <smbsrv/smb_door.h>
3311963SAfshin.Ardakani@Sun.COM
345331Samw
355331Samw /*
3611963SAfshin.Ardakani@Sun.COM * Generic XDR encoder.
375331Samw *
3811963SAfshin.Ardakani@Sun.COM * Returns a malloc'd, encoded buffer upon success.
3911963SAfshin.Ardakani@Sun.COM * Otherwise, returns NULL.
4011963SAfshin.Ardakani@Sun.COM */
4111963SAfshin.Ardakani@Sun.COM char *
smb_common_encode(void * data,xdrproc_t proc,size_t * rsize)4211963SAfshin.Ardakani@Sun.COM smb_common_encode(void *data, xdrproc_t proc, size_t *rsize)
4311963SAfshin.Ardakani@Sun.COM {
4411963SAfshin.Ardakani@Sun.COM XDR xdrs;
4511963SAfshin.Ardakani@Sun.COM char *buf;
4611963SAfshin.Ardakani@Sun.COM size_t len;
4711963SAfshin.Ardakani@Sun.COM
4811963SAfshin.Ardakani@Sun.COM if (proc == NULL || data == NULL || rsize == NULL) {
4911963SAfshin.Ardakani@Sun.COM syslog(LOG_ERR, "smb_common_encode: invalid parameter");
5011963SAfshin.Ardakani@Sun.COM return (NULL);
5111963SAfshin.Ardakani@Sun.COM }
5211963SAfshin.Ardakani@Sun.COM
5311963SAfshin.Ardakani@Sun.COM len = xdr_sizeof(proc, data);
5411963SAfshin.Ardakani@Sun.COM
5511963SAfshin.Ardakani@Sun.COM if ((buf = malloc(len)) == NULL) {
5611963SAfshin.Ardakani@Sun.COM syslog(LOG_ERR, "smb_common_encode: %m");
5711963SAfshin.Ardakani@Sun.COM *rsize = 0;
5811963SAfshin.Ardakani@Sun.COM return (NULL);
5911963SAfshin.Ardakani@Sun.COM }
6011963SAfshin.Ardakani@Sun.COM
6111963SAfshin.Ardakani@Sun.COM xdrmem_create(&xdrs, buf, len, XDR_ENCODE);
6211963SAfshin.Ardakani@Sun.COM *rsize = len;
6311963SAfshin.Ardakani@Sun.COM
6411963SAfshin.Ardakani@Sun.COM if (!proc(&xdrs, data)) {
6511963SAfshin.Ardakani@Sun.COM syslog(LOG_DEBUG, "smb_common_encode: encode error");
6611963SAfshin.Ardakani@Sun.COM free(buf);
6711963SAfshin.Ardakani@Sun.COM buf = NULL;
6811963SAfshin.Ardakani@Sun.COM *rsize = 0;
6911963SAfshin.Ardakani@Sun.COM }
7011963SAfshin.Ardakani@Sun.COM
7111963SAfshin.Ardakani@Sun.COM xdr_destroy(&xdrs);
7211963SAfshin.Ardakani@Sun.COM return (buf);
7311963SAfshin.Ardakani@Sun.COM }
7411963SAfshin.Ardakani@Sun.COM
7511963SAfshin.Ardakani@Sun.COM /*
7611963SAfshin.Ardakani@Sun.COM * Generic XDR decoder. Ensure that data is non-null and bzero'd.
775331Samw */
785331Samw int
smb_common_decode(char * buf,size_t len,xdrproc_t proc,void * data)7911963SAfshin.Ardakani@Sun.COM smb_common_decode(char *buf, size_t len, xdrproc_t proc, void *data)
805331Samw {
815331Samw XDR xdrs;
825331Samw int rc = 0;
835331Samw
8411963SAfshin.Ardakani@Sun.COM if (data == NULL)
855331Samw return (-1);
865331Samw
875331Samw xdrmem_create(&xdrs, buf, len, XDR_DECODE);
887588Samw@Sun.COM if (!proc(&xdrs, data))
895331Samw rc = -1;
907588Samw@Sun.COM
915331Samw xdr_destroy(&xdrs);
925331Samw return (rc);
935331Samw }
945331Samw
955331Samw char *
smb_string_encode(char * s,size_t * rsize)9611963SAfshin.Ardakani@Sun.COM smb_string_encode(char *s, size_t *rsize)
975331Samw {
9811963SAfshin.Ardakani@Sun.COM smb_string_t obj;
9911963SAfshin.Ardakani@Sun.COM XDR xdrs;
10011963SAfshin.Ardakani@Sun.COM char *buf = NULL;
10111963SAfshin.Ardakani@Sun.COM size_t len;
10211963SAfshin.Ardakani@Sun.COM
10311963SAfshin.Ardakani@Sun.COM if ((obj.buf = s) == NULL) {
10411963SAfshin.Ardakani@Sun.COM syslog(LOG_DEBUG, "smb_string_encode: invalid param");
10511963SAfshin.Ardakani@Sun.COM goto smb_string_encode_failed;
10611963SAfshin.Ardakani@Sun.COM }
10711963SAfshin.Ardakani@Sun.COM
10811963SAfshin.Ardakani@Sun.COM len = xdr_sizeof(smb_string_xdr, &obj);
10911963SAfshin.Ardakani@Sun.COM if ((buf = calloc(len, 1)) == NULL) {
11011963SAfshin.Ardakani@Sun.COM syslog(LOG_DEBUG, "smb_string_encode: %m");
11111963SAfshin.Ardakani@Sun.COM goto smb_string_encode_failed;
11211963SAfshin.Ardakani@Sun.COM }
1135331Samw
11411963SAfshin.Ardakani@Sun.COM xdrmem_create(&xdrs, buf, len, XDR_ENCODE);
11511963SAfshin.Ardakani@Sun.COM
11611963SAfshin.Ardakani@Sun.COM if (!smb_string_xdr(&xdrs, &obj)) {
11711963SAfshin.Ardakani@Sun.COM syslog(LOG_DEBUG, "smb_string_encode: encode failed");
11811963SAfshin.Ardakani@Sun.COM xdr_destroy(&xdrs);
11911963SAfshin.Ardakani@Sun.COM free(buf);
12011963SAfshin.Ardakani@Sun.COM goto smb_string_encode_failed;
12111963SAfshin.Ardakani@Sun.COM }
1225331Samw
12311963SAfshin.Ardakani@Sun.COM xdr_destroy(&xdrs);
12411963SAfshin.Ardakani@Sun.COM if (rsize)
12511963SAfshin.Ardakani@Sun.COM *rsize = len;
1265331Samw return (buf);
12711963SAfshin.Ardakani@Sun.COM
12811963SAfshin.Ardakani@Sun.COM smb_string_encode_failed:
12911963SAfshin.Ardakani@Sun.COM if (rsize)
13011963SAfshin.Ardakani@Sun.COM *rsize = 0;
13111963SAfshin.Ardakani@Sun.COM return (NULL);
1325331Samw }
1335331Samw
13411963SAfshin.Ardakani@Sun.COM int
smb_string_decode(smb_string_t * obj,char * buf,size_t buflen)13511963SAfshin.Ardakani@Sun.COM smb_string_decode(smb_string_t *obj, char *buf, size_t buflen)
1365331Samw {
13711963SAfshin.Ardakani@Sun.COM XDR xdrs;
13811963SAfshin.Ardakani@Sun.COM int rc = 0;
1395331Samw
14011963SAfshin.Ardakani@Sun.COM xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_DECODE);
1415331Samw
14211963SAfshin.Ardakani@Sun.COM bzero(obj, sizeof (smb_string_t));
14311963SAfshin.Ardakani@Sun.COM if (!smb_string_xdr(&xdrs, obj))
14411963SAfshin.Ardakani@Sun.COM rc = -1;
14511963SAfshin.Ardakani@Sun.COM
14611963SAfshin.Ardakani@Sun.COM xdr_destroy(&xdrs);
14711963SAfshin.Ardakani@Sun.COM return (rc);
1485331Samw }
14911337SWilliam.Krier@Sun.COM
15011337SWilliam.Krier@Sun.COM /*
15111337SWilliam.Krier@Sun.COM * Encode an lsa_account_t into a buffer.
15211337SWilliam.Krier@Sun.COM */
15311337SWilliam.Krier@Sun.COM int
lsa_account_encode(lsa_account_t * acct,uint8_t * buf,uint32_t buflen)15411337SWilliam.Krier@Sun.COM lsa_account_encode(lsa_account_t *acct, uint8_t *buf, uint32_t buflen)
15511337SWilliam.Krier@Sun.COM {
15611337SWilliam.Krier@Sun.COM XDR xdrs;
15711337SWilliam.Krier@Sun.COM int rc = 0;
15811337SWilliam.Krier@Sun.COM
15911337SWilliam.Krier@Sun.COM xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_ENCODE);
16011337SWilliam.Krier@Sun.COM
16111337SWilliam.Krier@Sun.COM if (!lsa_account_xdr(&xdrs, acct))
16211337SWilliam.Krier@Sun.COM rc = -1;
16311337SWilliam.Krier@Sun.COM
16411337SWilliam.Krier@Sun.COM xdr_destroy(&xdrs);
16511337SWilliam.Krier@Sun.COM return (rc);
16611337SWilliam.Krier@Sun.COM }
16711337SWilliam.Krier@Sun.COM
16811337SWilliam.Krier@Sun.COM /*
16911337SWilliam.Krier@Sun.COM * Decode an XDR buffer into an lsa_account_t.
17011337SWilliam.Krier@Sun.COM */
17111337SWilliam.Krier@Sun.COM int
lsa_account_decode(lsa_account_t * acct,uint8_t * buf,uint32_t buflen)17211337SWilliam.Krier@Sun.COM lsa_account_decode(lsa_account_t *acct, uint8_t *buf, uint32_t buflen)
17311337SWilliam.Krier@Sun.COM {
17411337SWilliam.Krier@Sun.COM XDR xdrs;
17511337SWilliam.Krier@Sun.COM int rc = 0;
17611337SWilliam.Krier@Sun.COM
17711337SWilliam.Krier@Sun.COM xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_DECODE);
17811337SWilliam.Krier@Sun.COM
17911337SWilliam.Krier@Sun.COM bzero(acct, sizeof (lsa_account_t));
18011337SWilliam.Krier@Sun.COM if (!lsa_account_xdr(&xdrs, acct))
18111337SWilliam.Krier@Sun.COM rc = -1;
18211337SWilliam.Krier@Sun.COM
18311337SWilliam.Krier@Sun.COM xdr_destroy(&xdrs);
18411337SWilliam.Krier@Sun.COM return (rc);
18511337SWilliam.Krier@Sun.COM }
18611337SWilliam.Krier@Sun.COM
18711337SWilliam.Krier@Sun.COM bool_t
lsa_account_xdr(XDR * xdrs,lsa_account_t * objp)18811337SWilliam.Krier@Sun.COM lsa_account_xdr(XDR *xdrs, lsa_account_t *objp)
18911337SWilliam.Krier@Sun.COM {
19011337SWilliam.Krier@Sun.COM if (!xdr_uint16_t(xdrs, &objp->a_sidtype))
19111337SWilliam.Krier@Sun.COM return (FALSE);
19211337SWilliam.Krier@Sun.COM if (!xdr_uint32_t(xdrs, &objp->a_status))
19311337SWilliam.Krier@Sun.COM return (FALSE);
19411337SWilliam.Krier@Sun.COM if (!xdr_vector(xdrs, (char *)objp->a_domain, MAXNAMELEN,
19511337SWilliam.Krier@Sun.COM sizeof (char), (xdrproc_t)xdr_char))
19611337SWilliam.Krier@Sun.COM return (FALSE);
19711337SWilliam.Krier@Sun.COM if (!xdr_vector(xdrs, (char *)objp->a_name, MAXNAMELEN,
19811337SWilliam.Krier@Sun.COM sizeof (char), (xdrproc_t)xdr_char))
19911337SWilliam.Krier@Sun.COM return (FALSE);
20011337SWilliam.Krier@Sun.COM if (!xdr_vector(xdrs, (char *)objp->a_sid, SMB_SID_STRSZ,
20111337SWilliam.Krier@Sun.COM sizeof (char), (xdrproc_t)xdr_char))
20211337SWilliam.Krier@Sun.COM return (FALSE);
20311337SWilliam.Krier@Sun.COM return (TRUE);
20411337SWilliam.Krier@Sun.COM }
205