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 /*
2212065SKeyur.Desai@Sun.COM * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
235331Samw */
245331Samw
2511963SAfshin.Ardakani@Sun.COM #include <sys/list.h>
2611963SAfshin.Ardakani@Sun.COM #include <assert.h>
275331Samw #include <alloca.h>
285331Samw #include <door.h>
295331Samw #include <errno.h>
305331Samw #include <syslog.h>
315331Samw #include <unistd.h>
325331Samw #include <stdio.h>
335331Samw #include <synch.h>
345331Samw #include <string.h>
355331Samw #include <stdlib.h>
365331Samw #include <sys/stat.h>
375331Samw #include <fcntl.h>
385331Samw #include <pthread.h>
395331Samw #include <strings.h>
4011963SAfshin.Ardakani@Sun.COM #include <smbsrv/smb_door.h>
4111963SAfshin.Ardakani@Sun.COM #include <smbsrv/smb_xdr.h>
4211963SAfshin.Ardakani@Sun.COM #include <smbsrv/smb_token.h>
4311963SAfshin.Ardakani@Sun.COM #include <smbsrv/libmlsvc.h>
4411963SAfshin.Ardakani@Sun.COM #include <smbsrv/libsmbns.h>
4511963SAfshin.Ardakani@Sun.COM #include "smbd.h"
465331Samw
4712065SKeyur.Desai@Sun.COM #define SMBD_ARG_MAGIC 0x53415247 /* 'SARG' */
4812065SKeyur.Desai@Sun.COM
4911963SAfshin.Ardakani@Sun.COM /*
5011963SAfshin.Ardakani@Sun.COM * Parameter for door operations.
5111963SAfshin.Ardakani@Sun.COM */
5211963SAfshin.Ardakani@Sun.COM typedef struct smbd_arg {
5312065SKeyur.Desai@Sun.COM uint32_t magic;
5411963SAfshin.Ardakani@Sun.COM list_node_t lnd;
5511963SAfshin.Ardakani@Sun.COM smb_doorhdr_t hdr;
5611963SAfshin.Ardakani@Sun.COM const char *opname;
5711963SAfshin.Ardakani@Sun.COM char *data;
5811963SAfshin.Ardakani@Sun.COM size_t datalen;
5911963SAfshin.Ardakani@Sun.COM char *rbuf;
6011963SAfshin.Ardakani@Sun.COM size_t rsize;
6112065SKeyur.Desai@Sun.COM boolean_t response_ready;
6212065SKeyur.Desai@Sun.COM boolean_t response_abort;
6311963SAfshin.Ardakani@Sun.COM uint32_t status;
6411963SAfshin.Ardakani@Sun.COM } smbd_arg_t;
655331Samw
665331Samw /*
6711963SAfshin.Ardakani@Sun.COM * The list contains asynchronous requests that have been initiated
6811963SAfshin.Ardakani@Sun.COM * but have not yet been collected (via smbd_dop_async_response).
6911963SAfshin.Ardakani@Sun.COM */
7011963SAfshin.Ardakani@Sun.COM typedef struct smbd_doorsvc {
7111963SAfshin.Ardakani@Sun.COM mutex_t sd_mutex;
7211963SAfshin.Ardakani@Sun.COM cond_t sd_cv;
7311963SAfshin.Ardakani@Sun.COM list_t sd_async_list;
7411963SAfshin.Ardakani@Sun.COM uint32_t sd_async_count;
7511963SAfshin.Ardakani@Sun.COM } smbd_doorsvc_t;
7611963SAfshin.Ardakani@Sun.COM
7711963SAfshin.Ardakani@Sun.COM static int smbd_dop_null(smbd_arg_t *);
7811963SAfshin.Ardakani@Sun.COM static int smbd_dop_async_response(smbd_arg_t *);
7911963SAfshin.Ardakani@Sun.COM static int smbd_dop_user_auth_logon(smbd_arg_t *);
8011963SAfshin.Ardakani@Sun.COM static int smbd_dop_user_nonauth_logon(smbd_arg_t *);
8111963SAfshin.Ardakani@Sun.COM static int smbd_dop_user_auth_logoff(smbd_arg_t *);
8211963SAfshin.Ardakani@Sun.COM static int smbd_dop_lookup_sid(smbd_arg_t *);
8311963SAfshin.Ardakani@Sun.COM static int smbd_dop_lookup_name(smbd_arg_t *);
8411963SAfshin.Ardakani@Sun.COM static int smbd_dop_join(smbd_arg_t *);
8511963SAfshin.Ardakani@Sun.COM static int smbd_dop_get_dcinfo(smbd_arg_t *);
8611963SAfshin.Ardakani@Sun.COM static int smbd_dop_vss_get_count(smbd_arg_t *);
8711963SAfshin.Ardakani@Sun.COM static int smbd_dop_vss_get_snapshots(smbd_arg_t *);
8811963SAfshin.Ardakani@Sun.COM static int smbd_dop_vss_map_gmttoken(smbd_arg_t *);
8911963SAfshin.Ardakani@Sun.COM static int smbd_dop_ads_find_host(smbd_arg_t *);
9011963SAfshin.Ardakani@Sun.COM static int smbd_dop_quota_query(smbd_arg_t *);
9111963SAfshin.Ardakani@Sun.COM static int smbd_dop_quota_set(smbd_arg_t *);
9211963SAfshin.Ardakani@Sun.COM static int smbd_dop_dfs_get_referrals(smbd_arg_t *);
93*12508Samw@Sun.COM static int smbd_dop_shr_hostaccess(smbd_arg_t *);
94*12508Samw@Sun.COM static int smbd_dop_shr_exec(smbd_arg_t *);
9511963SAfshin.Ardakani@Sun.COM
9611963SAfshin.Ardakani@Sun.COM typedef int (*smbd_dop_t)(smbd_arg_t *);
9711963SAfshin.Ardakani@Sun.COM
9811963SAfshin.Ardakani@Sun.COM typedef struct smbd_doorop {
9911963SAfshin.Ardakani@Sun.COM smb_dopcode_t opcode;
10011963SAfshin.Ardakani@Sun.COM smbd_dop_t op;
10111963SAfshin.Ardakani@Sun.COM } smbd_doorop_t;
10211963SAfshin.Ardakani@Sun.COM
10311963SAfshin.Ardakani@Sun.COM smbd_doorop_t smbd_doorops[] = {
10411963SAfshin.Ardakani@Sun.COM { SMB_DR_NULL, smbd_dop_null },
10511963SAfshin.Ardakani@Sun.COM { SMB_DR_ASYNC_RESPONSE, smbd_dop_async_response },
10611963SAfshin.Ardakani@Sun.COM { SMB_DR_USER_AUTH_LOGON, smbd_dop_user_auth_logon },
10711963SAfshin.Ardakani@Sun.COM { SMB_DR_USER_NONAUTH_LOGON, smbd_dop_user_nonauth_logon },
10811963SAfshin.Ardakani@Sun.COM { SMB_DR_USER_AUTH_LOGOFF, smbd_dop_user_auth_logoff },
10911963SAfshin.Ardakani@Sun.COM { SMB_DR_LOOKUP_SID, smbd_dop_lookup_sid },
11011963SAfshin.Ardakani@Sun.COM { SMB_DR_LOOKUP_NAME, smbd_dop_lookup_name },
11111963SAfshin.Ardakani@Sun.COM { SMB_DR_JOIN, smbd_dop_join },
11211963SAfshin.Ardakani@Sun.COM { SMB_DR_GET_DCINFO, smbd_dop_get_dcinfo },
11311963SAfshin.Ardakani@Sun.COM { SMB_DR_VSS_GET_COUNT, smbd_dop_vss_get_count },
11411963SAfshin.Ardakani@Sun.COM { SMB_DR_VSS_GET_SNAPSHOTS, smbd_dop_vss_get_snapshots },
11511963SAfshin.Ardakani@Sun.COM { SMB_DR_VSS_MAP_GMTTOKEN, smbd_dop_vss_map_gmttoken },
11611963SAfshin.Ardakani@Sun.COM { SMB_DR_ADS_FIND_HOST, smbd_dop_ads_find_host },
11711963SAfshin.Ardakani@Sun.COM { SMB_DR_QUOTA_QUERY, smbd_dop_quota_query },
11811963SAfshin.Ardakani@Sun.COM { SMB_DR_QUOTA_SET, smbd_dop_quota_set },
119*12508Samw@Sun.COM { SMB_DR_DFS_GET_REFERRALS, smbd_dop_dfs_get_referrals },
120*12508Samw@Sun.COM { SMB_DR_SHR_HOSTACCESS, smbd_dop_shr_hostaccess },
121*12508Samw@Sun.COM { SMB_DR_SHR_EXEC, smbd_dop_shr_exec }
12211963SAfshin.Ardakani@Sun.COM };
12311963SAfshin.Ardakani@Sun.COM
12411963SAfshin.Ardakani@Sun.COM static int smbd_ndoorop = (sizeof (smbd_doorops) / sizeof (smbd_doorops[0]));
12511963SAfshin.Ardakani@Sun.COM
12611963SAfshin.Ardakani@Sun.COM static smbd_doorsvc_t smbd_doorsvc;
12711963SAfshin.Ardakani@Sun.COM static int smbd_door_fd = -1;
12811963SAfshin.Ardakani@Sun.COM static int smbd_door_cookie = 0x534D4244; /* SMBD */
12911963SAfshin.Ardakani@Sun.COM static smbd_door_t smbd_door_sdh;
13011963SAfshin.Ardakani@Sun.COM
13111963SAfshin.Ardakani@Sun.COM static void smbd_door_dispatch(void *, char *, size_t, door_desc_t *, uint_t);
13211963SAfshin.Ardakani@Sun.COM static int smbd_door_dispatch_async(smbd_arg_t *);
13311963SAfshin.Ardakani@Sun.COM static void smbd_door_release_async(smbd_arg_t *);
13411963SAfshin.Ardakani@Sun.COM static void *smbd_door_dispatch_op(void *);
13511963SAfshin.Ardakani@Sun.COM
13611963SAfshin.Ardakani@Sun.COM /*
1375331Samw * Start the smbd door service. Create and bind to a door.
1385331Samw * Returns 0 on success. Otherwise, -1.
1395331Samw */
1405331Samw int
smbd_door_start(void)14111963SAfshin.Ardakani@Sun.COM smbd_door_start(void)
1425331Samw {
1436139Sjb150015 int newfd;
1445331Samw
14511963SAfshin.Ardakani@Sun.COM (void) mutex_lock(&smbd_doorsvc.sd_mutex);
1465331Samw
14711963SAfshin.Ardakani@Sun.COM if (smbd_door_fd != -1) {
1485331Samw (void) fprintf(stderr, "smb_doorsrv_start: already started");
14911963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&smbd_doorsvc.sd_mutex);
1505331Samw return (-1);
1515331Samw }
1525331Samw
15311963SAfshin.Ardakani@Sun.COM smbd_door_init(&smbd_door_sdh, "doorsrv");
15411963SAfshin.Ardakani@Sun.COM
15511963SAfshin.Ardakani@Sun.COM list_create(&smbd_doorsvc.sd_async_list, sizeof (smbd_arg_t),
15611963SAfshin.Ardakani@Sun.COM offsetof(smbd_arg_t, lnd));
15711963SAfshin.Ardakani@Sun.COM smbd_doorsvc.sd_async_count = 0;
15811963SAfshin.Ardakani@Sun.COM
15911963SAfshin.Ardakani@Sun.COM if ((smbd_door_fd = door_create(smbd_door_dispatch,
16011963SAfshin.Ardakani@Sun.COM &smbd_door_cookie, DOOR_UNREF)) < 0) {
1615331Samw (void) fprintf(stderr, "smb_doorsrv_start: door_create: %s",
1625331Samw strerror(errno));
16311963SAfshin.Ardakani@Sun.COM smbd_door_fd = -1;
16411963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&smbd_doorsvc.sd_mutex);
1655331Samw return (-1);
1665331Samw }
1675331Samw
16811963SAfshin.Ardakani@Sun.COM (void) unlink(SMBD_DOOR_NAME);
1695331Samw
17011963SAfshin.Ardakani@Sun.COM if ((newfd = creat(SMBD_DOOR_NAME, 0644)) < 0) {
1715331Samw (void) fprintf(stderr, "smb_doorsrv_start: open: %s",
1725331Samw strerror(errno));
17311963SAfshin.Ardakani@Sun.COM (void) door_revoke(smbd_door_fd);
17411963SAfshin.Ardakani@Sun.COM smbd_door_fd = -1;
17511963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&smbd_doorsvc.sd_mutex);
1765331Samw return (-1);
1775331Samw }
1785331Samw
1795331Samw (void) close(newfd);
18011963SAfshin.Ardakani@Sun.COM (void) fdetach(SMBD_DOOR_NAME);
1815331Samw
18211963SAfshin.Ardakani@Sun.COM if (fattach(smbd_door_fd, SMBD_DOOR_NAME) < 0) {
1835331Samw (void) fprintf(stderr, "smb_doorsrv_start: fattach: %s",
1845331Samw strerror(errno));
18511963SAfshin.Ardakani@Sun.COM (void) door_revoke(smbd_door_fd);
18611963SAfshin.Ardakani@Sun.COM smbd_door_fd = -1;
18711963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&smbd_doorsvc.sd_mutex);
1885331Samw return (-1);
1895331Samw }
1905331Samw
19111963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&smbd_doorsvc.sd_mutex);
19211963SAfshin.Ardakani@Sun.COM return (smbd_door_fd);
1935331Samw }
1945331Samw
1955331Samw /*
1965331Samw * Stop the smbd door service.
1975331Samw */
1985331Samw void
smbd_door_stop(void)19911963SAfshin.Ardakani@Sun.COM smbd_door_stop(void)
20011963SAfshin.Ardakani@Sun.COM {
20111963SAfshin.Ardakani@Sun.COM (void) mutex_lock(&smbd_doorsvc.sd_mutex);
20211963SAfshin.Ardakani@Sun.COM
20311963SAfshin.Ardakani@Sun.COM smbd_door_fini(&smbd_door_sdh);
20411963SAfshin.Ardakani@Sun.COM
20511963SAfshin.Ardakani@Sun.COM if (smbd_door_fd != -1) {
20611963SAfshin.Ardakani@Sun.COM (void) fdetach(SMBD_DOOR_NAME);
20711963SAfshin.Ardakani@Sun.COM (void) door_revoke(smbd_door_fd);
20811963SAfshin.Ardakani@Sun.COM smbd_door_fd = -1;
20911963SAfshin.Ardakani@Sun.COM }
21011963SAfshin.Ardakani@Sun.COM
21111963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&smbd_doorsvc.sd_mutex);
21211963SAfshin.Ardakani@Sun.COM }
21311963SAfshin.Ardakani@Sun.COM
21411963SAfshin.Ardakani@Sun.COM /*ARGSUSED*/
21511963SAfshin.Ardakani@Sun.COM static void
smbd_door_dispatch(void * cookie,char * argp,size_t arg_size,door_desc_t * dp,uint_t n_desc)21611963SAfshin.Ardakani@Sun.COM smbd_door_dispatch(void *cookie, char *argp, size_t arg_size, door_desc_t *dp,
21711963SAfshin.Ardakani@Sun.COM uint_t n_desc)
2185331Samw {
21911963SAfshin.Ardakani@Sun.COM smbd_arg_t dop_arg;
22011963SAfshin.Ardakani@Sun.COM smb_doorhdr_t *hdr;
22111963SAfshin.Ardakani@Sun.COM size_t hdr_size;
22211963SAfshin.Ardakani@Sun.COM char *rbuf = NULL;
22311963SAfshin.Ardakani@Sun.COM
22411963SAfshin.Ardakani@Sun.COM smbd_door_enter(&smbd_door_sdh);
22511963SAfshin.Ardakani@Sun.COM
22611963SAfshin.Ardakani@Sun.COM if (!smbd_online())
22711963SAfshin.Ardakani@Sun.COM smbd_door_return(&smbd_door_sdh, NULL, 0, NULL, 0);
22811963SAfshin.Ardakani@Sun.COM
22911963SAfshin.Ardakani@Sun.COM bzero(&dop_arg, sizeof (smbd_arg_t));
23011963SAfshin.Ardakani@Sun.COM hdr = &dop_arg.hdr;
23111963SAfshin.Ardakani@Sun.COM hdr_size = xdr_sizeof(smb_doorhdr_xdr, hdr);
23211963SAfshin.Ardakani@Sun.COM
23311963SAfshin.Ardakani@Sun.COM if ((cookie != &smbd_door_cookie) || (argp == NULL) ||
23411963SAfshin.Ardakani@Sun.COM (arg_size < hdr_size)) {
23511963SAfshin.Ardakani@Sun.COM smbd_door_return(&smbd_door_sdh, NULL, 0, NULL, 0);
23611963SAfshin.Ardakani@Sun.COM }
23711963SAfshin.Ardakani@Sun.COM
23811963SAfshin.Ardakani@Sun.COM if (smb_doorhdr_decode(hdr, (uint8_t *)argp, hdr_size) == -1) {
23911963SAfshin.Ardakani@Sun.COM syslog(LOG_DEBUG, "smbd_door_dispatch: header decode failed");
24011963SAfshin.Ardakani@Sun.COM smbd_door_return(&smbd_door_sdh, NULL, 0, NULL, 0);
24111963SAfshin.Ardakani@Sun.COM }
24211963SAfshin.Ardakani@Sun.COM
24311963SAfshin.Ardakani@Sun.COM if ((hdr->dh_magic != SMB_DOOR_HDR_MAGIC) || (hdr->dh_txid == 0)) {
24411963SAfshin.Ardakani@Sun.COM syslog(LOG_DEBUG, "smbd_door_dispatch: invalid header");
24511963SAfshin.Ardakani@Sun.COM smbd_door_return(&smbd_door_sdh, NULL, 0, NULL, 0);
24611963SAfshin.Ardakani@Sun.COM }
24711963SAfshin.Ardakani@Sun.COM
24811963SAfshin.Ardakani@Sun.COM dop_arg.opname = smb_doorhdr_opname(hdr->dh_op);
24911963SAfshin.Ardakani@Sun.COM dop_arg.data = argp + hdr_size;
25011963SAfshin.Ardakani@Sun.COM dop_arg.datalen = hdr->dh_datalen;
25111963SAfshin.Ardakani@Sun.COM
25211963SAfshin.Ardakani@Sun.COM if (hdr->dh_op == SMB_DR_ASYNC_RESPONSE) {
25311963SAfshin.Ardakani@Sun.COM /*
25411963SAfshin.Ardakani@Sun.COM * ASYNC_RESPONSE is used to collect the response
25511963SAfshin.Ardakani@Sun.COM * to an async call; it cannot be an async call.
25611963SAfshin.Ardakani@Sun.COM */
25711963SAfshin.Ardakani@Sun.COM hdr->dh_flags &= ~SMB_DF_ASYNC;
25811963SAfshin.Ardakani@Sun.COM }
25911963SAfshin.Ardakani@Sun.COM
26011963SAfshin.Ardakani@Sun.COM if (hdr->dh_flags & SMB_DF_ASYNC) {
26111963SAfshin.Ardakani@Sun.COM if (smbd_door_dispatch_async(&dop_arg) == 0)
26211963SAfshin.Ardakani@Sun.COM hdr->dh_door_rc = SMB_DOP_SUCCESS;
26311963SAfshin.Ardakani@Sun.COM else
26411963SAfshin.Ardakani@Sun.COM hdr->dh_door_rc = SMB_DOP_NOT_CALLED;
26511963SAfshin.Ardakani@Sun.COM } else {
26611963SAfshin.Ardakani@Sun.COM (void) smbd_door_dispatch_op(&dop_arg);
26711963SAfshin.Ardakani@Sun.COM }
2685331Samw
26911963SAfshin.Ardakani@Sun.COM if ((rbuf = (char *)alloca(dop_arg.rsize + hdr_size)) == NULL) {
27011963SAfshin.Ardakani@Sun.COM errno = ENOMEM;
27111963SAfshin.Ardakani@Sun.COM syslog(LOG_DEBUG, "smbd_door_dispatch[%s]: alloca %m",
27211963SAfshin.Ardakani@Sun.COM dop_arg.opname);
27311963SAfshin.Ardakani@Sun.COM smbd_door_return(&smbd_door_sdh, NULL, 0, NULL, 0);
27411963SAfshin.Ardakani@Sun.COM }
27511963SAfshin.Ardakani@Sun.COM
27611963SAfshin.Ardakani@Sun.COM if (dop_arg.rbuf != NULL) {
27711963SAfshin.Ardakani@Sun.COM (void) memcpy(rbuf + hdr_size, dop_arg.rbuf, dop_arg.rsize);
27811963SAfshin.Ardakani@Sun.COM free(dop_arg.rbuf);
27911963SAfshin.Ardakani@Sun.COM }
28011963SAfshin.Ardakani@Sun.COM
28111963SAfshin.Ardakani@Sun.COM hdr->dh_datalen = dop_arg.rsize;
28211963SAfshin.Ardakani@Sun.COM (void) smb_doorhdr_encode(hdr, (uint8_t *)rbuf, hdr_size);
28311963SAfshin.Ardakani@Sun.COM dop_arg.rsize += hdr_size;
28411963SAfshin.Ardakani@Sun.COM
28511963SAfshin.Ardakani@Sun.COM smbd_door_return(&smbd_door_sdh, rbuf, dop_arg.rsize, NULL, 0);
28611963SAfshin.Ardakani@Sun.COM /*NOTREACHED*/
28711963SAfshin.Ardakani@Sun.COM }
28811963SAfshin.Ardakani@Sun.COM
28911963SAfshin.Ardakani@Sun.COM /*
29011963SAfshin.Ardakani@Sun.COM * Launch a thread to process an asynchronous door call.
29111963SAfshin.Ardakani@Sun.COM */
29211963SAfshin.Ardakani@Sun.COM static int
smbd_door_dispatch_async(smbd_arg_t * req_arg)29311963SAfshin.Ardakani@Sun.COM smbd_door_dispatch_async(smbd_arg_t *req_arg)
29411963SAfshin.Ardakani@Sun.COM {
29511963SAfshin.Ardakani@Sun.COM smbd_arg_t *arg = NULL;
29611963SAfshin.Ardakani@Sun.COM char *data = NULL;
29711963SAfshin.Ardakani@Sun.COM pthread_attr_t attr;
29811963SAfshin.Ardakani@Sun.COM pthread_t tid;
29911963SAfshin.Ardakani@Sun.COM int rc;
30011963SAfshin.Ardakani@Sun.COM
30111963SAfshin.Ardakani@Sun.COM if ((req_arg->hdr.dh_flags & SMB_DF_ASYNC) == 0) {
30211963SAfshin.Ardakani@Sun.COM errno = EINVAL;
30311963SAfshin.Ardakani@Sun.COM return (-1);
30411963SAfshin.Ardakani@Sun.COM }
30511963SAfshin.Ardakani@Sun.COM
30611963SAfshin.Ardakani@Sun.COM if ((arg = malloc(sizeof (smbd_arg_t))) == NULL) {
30711963SAfshin.Ardakani@Sun.COM syslog(LOG_DEBUG, "smbd_door_dispatch_async[%s]: %m",
30811963SAfshin.Ardakani@Sun.COM req_arg->opname);
30911963SAfshin.Ardakani@Sun.COM return (-1);
31011963SAfshin.Ardakani@Sun.COM }
31111963SAfshin.Ardakani@Sun.COM
31211963SAfshin.Ardakani@Sun.COM (void) memcpy(arg, req_arg, sizeof (smbd_arg_t));
31311963SAfshin.Ardakani@Sun.COM arg->data = NULL;
31411963SAfshin.Ardakani@Sun.COM
31511963SAfshin.Ardakani@Sun.COM if (req_arg->datalen != 0) {
31611963SAfshin.Ardakani@Sun.COM if ((data = malloc(req_arg->datalen)) == NULL) {
31711963SAfshin.Ardakani@Sun.COM free(arg);
31811963SAfshin.Ardakani@Sun.COM syslog(LOG_DEBUG, "smbd_door_dispatch_async[%s]: %m",
31911963SAfshin.Ardakani@Sun.COM req_arg->opname);
32011963SAfshin.Ardakani@Sun.COM return (-1);
32111963SAfshin.Ardakani@Sun.COM }
32211963SAfshin.Ardakani@Sun.COM
32311963SAfshin.Ardakani@Sun.COM (void) memcpy(data, req_arg->data, req_arg->datalen);
32411963SAfshin.Ardakani@Sun.COM arg->data = data;
32511963SAfshin.Ardakani@Sun.COM }
32611963SAfshin.Ardakani@Sun.COM
32711963SAfshin.Ardakani@Sun.COM (void) mutex_lock(&smbd_doorsvc.sd_mutex);
32812065SKeyur.Desai@Sun.COM arg->magic = SMBD_ARG_MAGIC;
32911963SAfshin.Ardakani@Sun.COM list_insert_tail(&smbd_doorsvc.sd_async_list, arg);
33011963SAfshin.Ardakani@Sun.COM ++smbd_doorsvc.sd_async_count;
33111963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&smbd_doorsvc.sd_mutex);
33211963SAfshin.Ardakani@Sun.COM
33311963SAfshin.Ardakani@Sun.COM (void) pthread_attr_init(&attr);
33411963SAfshin.Ardakani@Sun.COM (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
33511963SAfshin.Ardakani@Sun.COM rc = pthread_create(&tid, &attr, smbd_door_dispatch_op, arg);
33611963SAfshin.Ardakani@Sun.COM (void) pthread_attr_destroy(&attr);
33711963SAfshin.Ardakani@Sun.COM
33811963SAfshin.Ardakani@Sun.COM if (rc != 0) {
33911963SAfshin.Ardakani@Sun.COM (void) mutex_lock(&smbd_doorsvc.sd_mutex);
34011963SAfshin.Ardakani@Sun.COM smbd_door_release_async(arg);
34111963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&smbd_doorsvc.sd_mutex);
3425331Samw }
3435331Samw
34411963SAfshin.Ardakani@Sun.COM return (rc);
34511963SAfshin.Ardakani@Sun.COM }
34611963SAfshin.Ardakani@Sun.COM
34711963SAfshin.Ardakani@Sun.COM /*
34811963SAfshin.Ardakani@Sun.COM * Remove an entry from the async response pending list and free
34911963SAfshin.Ardakani@Sun.COM * the arg and associated data.
35011963SAfshin.Ardakani@Sun.COM *
35111963SAfshin.Ardakani@Sun.COM * Must only be called while holding the smbd_doorsvc mutex.
35211963SAfshin.Ardakani@Sun.COM */
35311963SAfshin.Ardakani@Sun.COM static void
smbd_door_release_async(smbd_arg_t * arg)35411963SAfshin.Ardakani@Sun.COM smbd_door_release_async(smbd_arg_t *arg)
35511963SAfshin.Ardakani@Sun.COM {
35611963SAfshin.Ardakani@Sun.COM if (arg != NULL) {
35712065SKeyur.Desai@Sun.COM assert(arg->magic == SMBD_ARG_MAGIC);
35812065SKeyur.Desai@Sun.COM arg->magic = (uint32_t)~SMBD_ARG_MAGIC;
35912065SKeyur.Desai@Sun.COM
36011963SAfshin.Ardakani@Sun.COM list_remove(&smbd_doorsvc.sd_async_list, arg);
36111963SAfshin.Ardakani@Sun.COM --smbd_doorsvc.sd_async_count;
36211963SAfshin.Ardakani@Sun.COM free(arg->data);
36312065SKeyur.Desai@Sun.COM arg->data = NULL;
36411963SAfshin.Ardakani@Sun.COM free(arg);
36511963SAfshin.Ardakani@Sun.COM }
36611963SAfshin.Ardakani@Sun.COM }
36711963SAfshin.Ardakani@Sun.COM
36811963SAfshin.Ardakani@Sun.COM /*
36911963SAfshin.Ardakani@Sun.COM * All door calls are processed here: synchronous or asynchronous:
37011963SAfshin.Ardakani@Sun.COM * - synchronous calls are invoked by direct function call
37111963SAfshin.Ardakani@Sun.COM * - asynchronous calls are invoked from a launched thread
37211963SAfshin.Ardakani@Sun.COM *
37312065SKeyur.Desai@Sun.COM * If the kernel has attempted to collect a response before the op
37412065SKeyur.Desai@Sun.COM * has completed, the arg will have been marked as response_abort
37512065SKeyur.Desai@Sun.COM * and we can discard the response data and release the arg.
37612065SKeyur.Desai@Sun.COM *
37711963SAfshin.Ardakani@Sun.COM * We send a notification when asynchronous (ASYNC) door calls
37811963SAfshin.Ardakani@Sun.COM * from the kernel (SYSSPACE) have completed.
37911963SAfshin.Ardakani@Sun.COM */
38011963SAfshin.Ardakani@Sun.COM static void *
smbd_door_dispatch_op(void * thread_arg)38111963SAfshin.Ardakani@Sun.COM smbd_door_dispatch_op(void *thread_arg)
38211963SAfshin.Ardakani@Sun.COM {
38311963SAfshin.Ardakani@Sun.COM smbd_arg_t *arg = (smbd_arg_t *)thread_arg;
38411963SAfshin.Ardakani@Sun.COM smbd_doorop_t *doorop;
38511963SAfshin.Ardakani@Sun.COM smb_doorhdr_t *hdr;
38611963SAfshin.Ardakani@Sun.COM int i;
38711963SAfshin.Ardakani@Sun.COM
38811963SAfshin.Ardakani@Sun.COM if ((!smbd_online()) || arg == NULL)
38911963SAfshin.Ardakani@Sun.COM return (NULL);
39011963SAfshin.Ardakani@Sun.COM
39111963SAfshin.Ardakani@Sun.COM hdr = &arg->hdr;
39211963SAfshin.Ardakani@Sun.COM arg->opname = smb_doorhdr_opname(hdr->dh_op);
39311963SAfshin.Ardakani@Sun.COM
39411963SAfshin.Ardakani@Sun.COM for (i = 0; i < smbd_ndoorop; ++i) {
39511963SAfshin.Ardakani@Sun.COM doorop = &smbd_doorops[i];
39611963SAfshin.Ardakani@Sun.COM
39711963SAfshin.Ardakani@Sun.COM if (hdr->dh_op == doorop->opcode) {
39811963SAfshin.Ardakani@Sun.COM hdr->dh_door_rc = doorop->op(arg);
39911963SAfshin.Ardakani@Sun.COM hdr->dh_status = arg->status;
40011963SAfshin.Ardakani@Sun.COM
40111963SAfshin.Ardakani@Sun.COM if ((hdr->dh_flags & SMB_DF_SYSSPACE) &&
40211963SAfshin.Ardakani@Sun.COM (hdr->dh_flags & SMB_DF_ASYNC)) {
40311963SAfshin.Ardakani@Sun.COM assert(hdr->dh_op != SMB_DR_ASYNC_RESPONSE);
40412065SKeyur.Desai@Sun.COM
40512065SKeyur.Desai@Sun.COM (void) mutex_lock(&smbd_doorsvc.sd_mutex);
40612065SKeyur.Desai@Sun.COM if (arg->response_abort) {
40712065SKeyur.Desai@Sun.COM free(arg->rbuf);
40812065SKeyur.Desai@Sun.COM arg->rbuf = NULL;
40912065SKeyur.Desai@Sun.COM smbd_door_release_async(arg);
41012065SKeyur.Desai@Sun.COM } else {
41112065SKeyur.Desai@Sun.COM arg->response_ready = B_TRUE;
41212065SKeyur.Desai@Sun.COM }
41312065SKeyur.Desai@Sun.COM (void) mutex_unlock(&smbd_doorsvc.sd_mutex);
41412065SKeyur.Desai@Sun.COM
41511963SAfshin.Ardakani@Sun.COM (void) smb_kmod_event_notify(hdr->dh_txid);
41611963SAfshin.Ardakani@Sun.COM }
41711963SAfshin.Ardakani@Sun.COM
41811963SAfshin.Ardakani@Sun.COM return (NULL);
41911963SAfshin.Ardakani@Sun.COM }
42011963SAfshin.Ardakani@Sun.COM }
42111963SAfshin.Ardakani@Sun.COM
42211963SAfshin.Ardakani@Sun.COM syslog(LOG_ERR, "smbd_door_dispatch_op[%s]: invalid op %u",
42311963SAfshin.Ardakani@Sun.COM arg->opname, hdr->dh_op);
42411963SAfshin.Ardakani@Sun.COM return (NULL);
42511963SAfshin.Ardakani@Sun.COM }
42611963SAfshin.Ardakani@Sun.COM
42711963SAfshin.Ardakani@Sun.COM /*
42811963SAfshin.Ardakani@Sun.COM * Wrapper for door_return. smbd_door_enter() increments a reference count
42911963SAfshin.Ardakani@Sun.COM * when a door call is dispatched and smbd_door_return() decrements the
43011963SAfshin.Ardakani@Sun.COM * reference count when it completes.
43111963SAfshin.Ardakani@Sun.COM *
43211963SAfshin.Ardakani@Sun.COM * The reference counting is used in smbd_door_fini() to wait for active
43311963SAfshin.Ardakani@Sun.COM * calls to complete before closing the door.
43411963SAfshin.Ardakani@Sun.COM */
43511963SAfshin.Ardakani@Sun.COM void
smbd_door_init(smbd_door_t * sdh,const char * name)43611963SAfshin.Ardakani@Sun.COM smbd_door_init(smbd_door_t *sdh, const char *name)
43711963SAfshin.Ardakani@Sun.COM {
43811963SAfshin.Ardakani@Sun.COM (void) strlcpy(sdh->sd_name, name, SMBD_DOOR_NAMESZ);
43911963SAfshin.Ardakani@Sun.COM }
44011963SAfshin.Ardakani@Sun.COM
44111963SAfshin.Ardakani@Sun.COM void
smbd_door_enter(smbd_door_t * sdh)44211963SAfshin.Ardakani@Sun.COM smbd_door_enter(smbd_door_t *sdh)
44311963SAfshin.Ardakani@Sun.COM {
44411963SAfshin.Ardakani@Sun.COM (void) mutex_lock(&sdh->sd_mutex);
44511963SAfshin.Ardakani@Sun.COM ++sdh->sd_ncalls;
44611963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&sdh->sd_mutex);
44711963SAfshin.Ardakani@Sun.COM }
44811963SAfshin.Ardakani@Sun.COM
44911963SAfshin.Ardakani@Sun.COM /*
45011963SAfshin.Ardakani@Sun.COM * We have two calls to door_return because the first call (with data)
45111963SAfshin.Ardakani@Sun.COM * can fail, which can leave the door call blocked here. The second
45211963SAfshin.Ardakani@Sun.COM * call (with NULL) is guaranteed to unblock and return to the caller.
45311963SAfshin.Ardakani@Sun.COM */
45411963SAfshin.Ardakani@Sun.COM void
smbd_door_return(smbd_door_t * sdh,char * data_ptr,size_t data_size,door_desc_t * desc_ptr,uint_t num_desc)45511963SAfshin.Ardakani@Sun.COM smbd_door_return(smbd_door_t *sdh, char *data_ptr, size_t data_size,
45611963SAfshin.Ardakani@Sun.COM door_desc_t *desc_ptr, uint_t num_desc)
45711963SAfshin.Ardakani@Sun.COM {
45811963SAfshin.Ardakani@Sun.COM (void) mutex_lock(&sdh->sd_mutex);
45911963SAfshin.Ardakani@Sun.COM
46011963SAfshin.Ardakani@Sun.COM if (sdh->sd_ncalls == 0)
46111963SAfshin.Ardakani@Sun.COM syslog(LOG_ERR, "smbd_door_return[%s]: unexpected count=0",
46211963SAfshin.Ardakani@Sun.COM sdh->sd_name);
46311963SAfshin.Ardakani@Sun.COM else
46411963SAfshin.Ardakani@Sun.COM --sdh->sd_ncalls;
46511963SAfshin.Ardakani@Sun.COM
46611963SAfshin.Ardakani@Sun.COM (void) cond_broadcast(&sdh->sd_cv);
46711963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&sdh->sd_mutex);
46811963SAfshin.Ardakani@Sun.COM
46911963SAfshin.Ardakani@Sun.COM (void) door_return(data_ptr, data_size, desc_ptr, num_desc);
47011963SAfshin.Ardakani@Sun.COM (void) door_return(NULL, 0, NULL, 0);
47111963SAfshin.Ardakani@Sun.COM /* NOTREACHED */
47211963SAfshin.Ardakani@Sun.COM }
47311963SAfshin.Ardakani@Sun.COM
47411963SAfshin.Ardakani@Sun.COM /*
47511963SAfshin.Ardakani@Sun.COM * A door service is about to terminate.
47611963SAfshin.Ardakani@Sun.COM * Give active requests a small grace period to complete.
47711963SAfshin.Ardakani@Sun.COM */
47811963SAfshin.Ardakani@Sun.COM void
smbd_door_fini(smbd_door_t * sdh)47911963SAfshin.Ardakani@Sun.COM smbd_door_fini(smbd_door_t *sdh)
48011963SAfshin.Ardakani@Sun.COM {
48111963SAfshin.Ardakani@Sun.COM timestruc_t delay;
48211963SAfshin.Ardakani@Sun.COM int rc = 0;
48311963SAfshin.Ardakani@Sun.COM
48411963SAfshin.Ardakani@Sun.COM (void) mutex_lock(&sdh->sd_mutex);
48511963SAfshin.Ardakani@Sun.COM
48611963SAfshin.Ardakani@Sun.COM while (rc != ETIME && sdh->sd_ncalls != 0) {
48711963SAfshin.Ardakani@Sun.COM delay.tv_sec = 1;
48811963SAfshin.Ardakani@Sun.COM delay.tv_nsec = 0;
48911963SAfshin.Ardakani@Sun.COM rc = cond_reltimedwait(&sdh->sd_cv, &sdh->sd_mutex, &delay);
49011963SAfshin.Ardakani@Sun.COM }
49111963SAfshin.Ardakani@Sun.COM
49211963SAfshin.Ardakani@Sun.COM if (sdh->sd_ncalls != 0)
49311963SAfshin.Ardakani@Sun.COM syslog(LOG_NOTICE, "smbd_door_fini[%s]: %d remaining",
49411963SAfshin.Ardakani@Sun.COM sdh->sd_name, sdh->sd_ncalls);
49511963SAfshin.Ardakani@Sun.COM
49611963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&sdh->sd_mutex);
49711963SAfshin.Ardakani@Sun.COM }
49811963SAfshin.Ardakani@Sun.COM
49911963SAfshin.Ardakani@Sun.COM /*
50011963SAfshin.Ardakani@Sun.COM * Null door operation: always returns success.
50111963SAfshin.Ardakani@Sun.COM * Assumes no request or response data.
50211963SAfshin.Ardakani@Sun.COM */
50311963SAfshin.Ardakani@Sun.COM /*ARGSUSED*/
50411963SAfshin.Ardakani@Sun.COM static int
smbd_dop_null(smbd_arg_t * arg)50511963SAfshin.Ardakani@Sun.COM smbd_dop_null(smbd_arg_t *arg)
50611963SAfshin.Ardakani@Sun.COM {
50711963SAfshin.Ardakani@Sun.COM return (SMB_DOP_SUCCESS);
5085331Samw }
5095331Samw
5105331Samw /*
51111963SAfshin.Ardakani@Sun.COM * Async response handler: setup the rbuf and rsize for the specified
51211963SAfshin.Ardakani@Sun.COM * transaction. This function is used by the kernel to collect the
51311963SAfshin.Ardakani@Sun.COM * response half of an asynchronous door call.
51412065SKeyur.Desai@Sun.COM *
51512065SKeyur.Desai@Sun.COM * If a door client attempts to collect a response before the op has
51612065SKeyur.Desai@Sun.COM * completed (!response_ready), mark the arg as response_abort and
51712065SKeyur.Desai@Sun.COM * set an error. The response will be discarded when the op completes.
51811963SAfshin.Ardakani@Sun.COM */
51911963SAfshin.Ardakani@Sun.COM static int
smbd_dop_async_response(smbd_arg_t * rsp_arg)52011963SAfshin.Ardakani@Sun.COM smbd_dop_async_response(smbd_arg_t *rsp_arg)
52111963SAfshin.Ardakani@Sun.COM {
52211963SAfshin.Ardakani@Sun.COM list_t *arg_list = &smbd_doorsvc.sd_async_list;
52311963SAfshin.Ardakani@Sun.COM smbd_arg_t *arg;
52411963SAfshin.Ardakani@Sun.COM
52511963SAfshin.Ardakani@Sun.COM (void) mutex_lock(&smbd_doorsvc.sd_mutex);
52611963SAfshin.Ardakani@Sun.COM arg = list_head(arg_list);
52711963SAfshin.Ardakani@Sun.COM
52811963SAfshin.Ardakani@Sun.COM while (arg != NULL) {
52912065SKeyur.Desai@Sun.COM assert(arg->magic == SMBD_ARG_MAGIC);
53012065SKeyur.Desai@Sun.COM
53111963SAfshin.Ardakani@Sun.COM if (arg->hdr.dh_txid == rsp_arg->hdr.dh_txid) {
53212065SKeyur.Desai@Sun.COM if (!arg->response_ready) {
53312065SKeyur.Desai@Sun.COM arg->response_abort = B_TRUE;
53412065SKeyur.Desai@Sun.COM rsp_arg->hdr.dh_door_rc = SMB_DOP_NOT_CALLED;
53512065SKeyur.Desai@Sun.COM syslog(LOG_NOTICE, "doorsvc[%s]: %u not ready",
53612065SKeyur.Desai@Sun.COM arg->opname, arg->hdr.dh_txid);
53712065SKeyur.Desai@Sun.COM break;
53812065SKeyur.Desai@Sun.COM }
53912065SKeyur.Desai@Sun.COM
54011963SAfshin.Ardakani@Sun.COM rsp_arg->rbuf = arg->rbuf;
54111963SAfshin.Ardakani@Sun.COM rsp_arg->rsize = arg->rsize;
54211963SAfshin.Ardakani@Sun.COM arg->rbuf = NULL;
54311963SAfshin.Ardakani@Sun.COM arg->rsize = 0;
54411963SAfshin.Ardakani@Sun.COM smbd_door_release_async(arg);
54511963SAfshin.Ardakani@Sun.COM break;
54611963SAfshin.Ardakani@Sun.COM }
54711963SAfshin.Ardakani@Sun.COM
54811963SAfshin.Ardakani@Sun.COM arg = list_next(arg_list, arg);
54911963SAfshin.Ardakani@Sun.COM }
55011963SAfshin.Ardakani@Sun.COM
55111963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&smbd_doorsvc.sd_mutex);
55211963SAfshin.Ardakani@Sun.COM return (SMB_DOP_SUCCESS);
55311963SAfshin.Ardakani@Sun.COM }
55411963SAfshin.Ardakani@Sun.COM
55511963SAfshin.Ardakani@Sun.COM static int
smbd_dop_user_nonauth_logon(smbd_arg_t * arg)55611963SAfshin.Ardakani@Sun.COM smbd_dop_user_nonauth_logon(smbd_arg_t *arg)
55711963SAfshin.Ardakani@Sun.COM {
55812065SKeyur.Desai@Sun.COM uint32_t sid = 0;
55911963SAfshin.Ardakani@Sun.COM
56011963SAfshin.Ardakani@Sun.COM if (smb_common_decode(arg->data, arg->datalen,
56111963SAfshin.Ardakani@Sun.COM xdr_uint32_t, &sid) != 0)
56211963SAfshin.Ardakani@Sun.COM return (SMB_DOP_DECODE_ERROR);
56311963SAfshin.Ardakani@Sun.COM
56411963SAfshin.Ardakani@Sun.COM smbd_user_nonauth_logon(sid);
56511963SAfshin.Ardakani@Sun.COM return (SMB_DOP_SUCCESS);
56611963SAfshin.Ardakani@Sun.COM }
56711963SAfshin.Ardakani@Sun.COM
56811963SAfshin.Ardakani@Sun.COM static int
smbd_dop_user_auth_logoff(smbd_arg_t * arg)56911963SAfshin.Ardakani@Sun.COM smbd_dop_user_auth_logoff(smbd_arg_t *arg)
57011963SAfshin.Ardakani@Sun.COM {
57112065SKeyur.Desai@Sun.COM uint32_t sid = 0;
57211963SAfshin.Ardakani@Sun.COM
57311963SAfshin.Ardakani@Sun.COM if (smb_common_decode(arg->data, arg->datalen,
57411963SAfshin.Ardakani@Sun.COM xdr_uint32_t, &sid) != 0)
57511963SAfshin.Ardakani@Sun.COM return (SMB_DOP_DECODE_ERROR);
57611963SAfshin.Ardakani@Sun.COM
57711963SAfshin.Ardakani@Sun.COM smbd_user_auth_logoff(sid);
57811963SAfshin.Ardakani@Sun.COM return (SMB_DOP_SUCCESS);
57911963SAfshin.Ardakani@Sun.COM }
58011963SAfshin.Ardakani@Sun.COM
58111963SAfshin.Ardakani@Sun.COM /*
58211963SAfshin.Ardakani@Sun.COM * Obtains an access token on successful user authentication.
5835331Samw */
58411963SAfshin.Ardakani@Sun.COM static int
smbd_dop_user_auth_logon(smbd_arg_t * arg)58511963SAfshin.Ardakani@Sun.COM smbd_dop_user_auth_logon(smbd_arg_t *arg)
58611963SAfshin.Ardakani@Sun.COM {
58711963SAfshin.Ardakani@Sun.COM smb_logon_t *user_info;
58811963SAfshin.Ardakani@Sun.COM smb_token_t *token;
58911963SAfshin.Ardakani@Sun.COM
59011963SAfshin.Ardakani@Sun.COM user_info = smb_logon_decode((uint8_t *)arg->data,
59111963SAfshin.Ardakani@Sun.COM arg->datalen);
59211963SAfshin.Ardakani@Sun.COM if (user_info == NULL)
59311963SAfshin.Ardakani@Sun.COM return (SMB_DOP_DECODE_ERROR);
59411963SAfshin.Ardakani@Sun.COM
59511963SAfshin.Ardakani@Sun.COM token = smbd_user_auth_logon(user_info);
59611963SAfshin.Ardakani@Sun.COM
59711963SAfshin.Ardakani@Sun.COM smb_logon_free(user_info);
59811963SAfshin.Ardakani@Sun.COM
59911963SAfshin.Ardakani@Sun.COM if (token == NULL)
60011963SAfshin.Ardakani@Sun.COM return (SMB_DOP_EMPTYBUF);
60111963SAfshin.Ardakani@Sun.COM
60211963SAfshin.Ardakani@Sun.COM arg->rbuf = (char *)smb_token_encode(token, &arg->rsize);
60311963SAfshin.Ardakani@Sun.COM smb_token_destroy(token);
60411963SAfshin.Ardakani@Sun.COM
60511963SAfshin.Ardakani@Sun.COM if (arg->rbuf == NULL)
60611963SAfshin.Ardakani@Sun.COM return (SMB_DOP_ENCODE_ERROR);
60711963SAfshin.Ardakani@Sun.COM return (SMB_DOP_SUCCESS);
60811963SAfshin.Ardakani@Sun.COM }
60911963SAfshin.Ardakani@Sun.COM
61011963SAfshin.Ardakani@Sun.COM static int
smbd_dop_lookup_name(smbd_arg_t * arg)61111963SAfshin.Ardakani@Sun.COM smbd_dop_lookup_name(smbd_arg_t *arg)
61211963SAfshin.Ardakani@Sun.COM {
61311963SAfshin.Ardakani@Sun.COM smb_domain_t dinfo;
61411963SAfshin.Ardakani@Sun.COM smb_account_t ainfo;
61511963SAfshin.Ardakani@Sun.COM lsa_account_t acct;
61611963SAfshin.Ardakani@Sun.COM char buf[MAXNAMELEN];
61711963SAfshin.Ardakani@Sun.COM
61812065SKeyur.Desai@Sun.COM bzero(&acct, sizeof (lsa_account_t));
61912065SKeyur.Desai@Sun.COM
62011963SAfshin.Ardakani@Sun.COM if (smb_common_decode(arg->data, arg->datalen,
62111963SAfshin.Ardakani@Sun.COM lsa_account_xdr, &acct) != 0)
62211963SAfshin.Ardakani@Sun.COM return (SMB_DOP_DECODE_ERROR);
62311963SAfshin.Ardakani@Sun.COM
62411963SAfshin.Ardakani@Sun.COM if (*acct.a_domain == '\0')
62511963SAfshin.Ardakani@Sun.COM (void) snprintf(buf, MAXNAMELEN, "%s", acct.a_name);
62611963SAfshin.Ardakani@Sun.COM else if (strchr(acct.a_domain, '.') != NULL)
62711963SAfshin.Ardakani@Sun.COM (void) snprintf(buf, MAXNAMELEN, "%s@%s", acct.a_name,
62811963SAfshin.Ardakani@Sun.COM acct.a_domain);
62911963SAfshin.Ardakani@Sun.COM else
63011963SAfshin.Ardakani@Sun.COM (void) snprintf(buf, MAXNAMELEN, "%s\\%s", acct.a_domain,
63111963SAfshin.Ardakani@Sun.COM acct.a_name);
63211963SAfshin.Ardakani@Sun.COM
63311963SAfshin.Ardakani@Sun.COM acct.a_status = lsa_lookup_name(buf, acct.a_sidtype, &ainfo);
63411963SAfshin.Ardakani@Sun.COM if (acct.a_status == NT_STATUS_SUCCESS) {
63511963SAfshin.Ardakani@Sun.COM acct.a_sidtype = ainfo.a_type;
63611963SAfshin.Ardakani@Sun.COM smb_sid_tostr(ainfo.a_sid, acct.a_sid);
63711963SAfshin.Ardakani@Sun.COM (void) strlcpy(acct.a_name, ainfo.a_name, MAXNAMELEN);
63811963SAfshin.Ardakani@Sun.COM
63911963SAfshin.Ardakani@Sun.COM if (smb_domain_lookup_name(ainfo.a_domain, &dinfo))
64011963SAfshin.Ardakani@Sun.COM (void) strlcpy(acct.a_domain, dinfo.di_fqname,
64111963SAfshin.Ardakani@Sun.COM MAXNAMELEN);
64211963SAfshin.Ardakani@Sun.COM else
64311963SAfshin.Ardakani@Sun.COM (void) strlcpy(acct.a_domain, ainfo.a_domain,
64411963SAfshin.Ardakani@Sun.COM MAXNAMELEN);
64511963SAfshin.Ardakani@Sun.COM smb_account_free(&ainfo);
64611963SAfshin.Ardakani@Sun.COM }
64711963SAfshin.Ardakani@Sun.COM
64811963SAfshin.Ardakani@Sun.COM arg->rbuf = smb_common_encode(&acct, lsa_account_xdr, &arg->rsize);
64911963SAfshin.Ardakani@Sun.COM
65011963SAfshin.Ardakani@Sun.COM if (arg->rbuf == NULL)
65111963SAfshin.Ardakani@Sun.COM return (SMB_DOP_ENCODE_ERROR);
65211963SAfshin.Ardakani@Sun.COM return (SMB_DOP_SUCCESS);
65311963SAfshin.Ardakani@Sun.COM }
65411963SAfshin.Ardakani@Sun.COM
65511963SAfshin.Ardakani@Sun.COM static int
smbd_dop_lookup_sid(smbd_arg_t * arg)65611963SAfshin.Ardakani@Sun.COM smbd_dop_lookup_sid(smbd_arg_t *arg)
65711963SAfshin.Ardakani@Sun.COM {
65811963SAfshin.Ardakani@Sun.COM smb_domain_t dinfo;
65911963SAfshin.Ardakani@Sun.COM smb_account_t ainfo;
66011963SAfshin.Ardakani@Sun.COM lsa_account_t acct;
66111963SAfshin.Ardakani@Sun.COM smb_sid_t *sid;
66211963SAfshin.Ardakani@Sun.COM
66312065SKeyur.Desai@Sun.COM bzero(&acct, sizeof (lsa_account_t));
66412065SKeyur.Desai@Sun.COM
66511963SAfshin.Ardakani@Sun.COM if (smb_common_decode(arg->data, arg->datalen,
66611963SAfshin.Ardakani@Sun.COM lsa_account_xdr, &acct) != 0)
66711963SAfshin.Ardakani@Sun.COM return (SMB_DOP_DECODE_ERROR);
66811963SAfshin.Ardakani@Sun.COM
66911963SAfshin.Ardakani@Sun.COM sid = smb_sid_fromstr(acct.a_sid);
67011963SAfshin.Ardakani@Sun.COM acct.a_status = lsa_lookup_sid(sid, &ainfo);
67111963SAfshin.Ardakani@Sun.COM smb_sid_free(sid);
67211963SAfshin.Ardakani@Sun.COM
67311963SAfshin.Ardakani@Sun.COM if (acct.a_status == NT_STATUS_SUCCESS) {
67411963SAfshin.Ardakani@Sun.COM acct.a_sidtype = ainfo.a_type;
67511963SAfshin.Ardakani@Sun.COM smb_sid_tostr(ainfo.a_sid, acct.a_sid);
67611963SAfshin.Ardakani@Sun.COM (void) strlcpy(acct.a_name, ainfo.a_name, MAXNAMELEN);
67711963SAfshin.Ardakani@Sun.COM
67811963SAfshin.Ardakani@Sun.COM if (smb_domain_lookup_name(ainfo.a_domain, &dinfo))
67911963SAfshin.Ardakani@Sun.COM (void) strlcpy(acct.a_domain, dinfo.di_fqname,
68011963SAfshin.Ardakani@Sun.COM MAXNAMELEN);
68111963SAfshin.Ardakani@Sun.COM else
68211963SAfshin.Ardakani@Sun.COM (void) strlcpy(acct.a_domain, ainfo.a_domain,
68311963SAfshin.Ardakani@Sun.COM MAXNAMELEN);
68411963SAfshin.Ardakani@Sun.COM
68511963SAfshin.Ardakani@Sun.COM smb_account_free(&ainfo);
68611963SAfshin.Ardakani@Sun.COM }
68711963SAfshin.Ardakani@Sun.COM
68811963SAfshin.Ardakani@Sun.COM arg->rbuf = smb_common_encode(&acct, lsa_account_xdr, &arg->rsize);
68911963SAfshin.Ardakani@Sun.COM
69011963SAfshin.Ardakani@Sun.COM if (arg->rbuf == NULL)
69111963SAfshin.Ardakani@Sun.COM return (SMB_DOP_ENCODE_ERROR);
69211963SAfshin.Ardakani@Sun.COM return (SMB_DOP_SUCCESS);
69311963SAfshin.Ardakani@Sun.COM }
69411963SAfshin.Ardakani@Sun.COM
69511963SAfshin.Ardakani@Sun.COM static int
smbd_dop_join(smbd_arg_t * arg)69611963SAfshin.Ardakani@Sun.COM smbd_dop_join(smbd_arg_t *arg)
6975331Samw {
69811963SAfshin.Ardakani@Sun.COM smb_joininfo_t jdi;
69911963SAfshin.Ardakani@Sun.COM uint32_t status;
70011963SAfshin.Ardakani@Sun.COM
70112065SKeyur.Desai@Sun.COM bzero(&jdi, sizeof (smb_joininfo_t));
70212065SKeyur.Desai@Sun.COM
70311963SAfshin.Ardakani@Sun.COM if (smb_common_decode(arg->data, arg->datalen,
70411963SAfshin.Ardakani@Sun.COM smb_joininfo_xdr, &jdi) != 0)
70511963SAfshin.Ardakani@Sun.COM return (SMB_DOP_DECODE_ERROR);
70611963SAfshin.Ardakani@Sun.COM
70711963SAfshin.Ardakani@Sun.COM status = smbd_join(&jdi);
70811963SAfshin.Ardakani@Sun.COM
70911963SAfshin.Ardakani@Sun.COM arg->rbuf = smb_common_encode(&status, xdr_uint32_t, &arg->rsize);
71011963SAfshin.Ardakani@Sun.COM
71111963SAfshin.Ardakani@Sun.COM if (arg->rbuf == NULL)
71211963SAfshin.Ardakani@Sun.COM return (SMB_DOP_ENCODE_ERROR);
71311963SAfshin.Ardakani@Sun.COM return (SMB_DOP_SUCCESS);
71411963SAfshin.Ardakani@Sun.COM }
71511963SAfshin.Ardakani@Sun.COM
71611963SAfshin.Ardakani@Sun.COM static int
smbd_dop_get_dcinfo(smbd_arg_t * arg)71711963SAfshin.Ardakani@Sun.COM smbd_dop_get_dcinfo(smbd_arg_t *arg)
71811963SAfshin.Ardakani@Sun.COM {
71911963SAfshin.Ardakani@Sun.COM smb_domainex_t dxi;
72011963SAfshin.Ardakani@Sun.COM
72111963SAfshin.Ardakani@Sun.COM if (!smb_domain_getinfo(&dxi))
72211963SAfshin.Ardakani@Sun.COM return (SMB_DOP_EMPTYBUF);
72311963SAfshin.Ardakani@Sun.COM
72411963SAfshin.Ardakani@Sun.COM arg->rbuf = smb_string_encode(dxi.d_dc, &arg->rsize);
72511963SAfshin.Ardakani@Sun.COM
72611963SAfshin.Ardakani@Sun.COM if (arg->rbuf == NULL)
72711963SAfshin.Ardakani@Sun.COM return (SMB_DOP_ENCODE_ERROR);
72811963SAfshin.Ardakani@Sun.COM return (SMB_DOP_SUCCESS);
72911963SAfshin.Ardakani@Sun.COM }
73011963SAfshin.Ardakani@Sun.COM
73111963SAfshin.Ardakani@Sun.COM /*
73211963SAfshin.Ardakani@Sun.COM * Return the number of snapshots for a dataset
73311963SAfshin.Ardakani@Sun.COM */
73411963SAfshin.Ardakani@Sun.COM static int
smbd_dop_vss_get_count(smbd_arg_t * arg)73511963SAfshin.Ardakani@Sun.COM smbd_dop_vss_get_count(smbd_arg_t *arg)
73611963SAfshin.Ardakani@Sun.COM {
73711963SAfshin.Ardakani@Sun.COM smb_string_t path;
73811963SAfshin.Ardakani@Sun.COM uint32_t count;
73911963SAfshin.Ardakani@Sun.COM
74011963SAfshin.Ardakani@Sun.COM bzero(&path, sizeof (smb_string_t));
74111963SAfshin.Ardakani@Sun.COM arg->rbuf = NULL;
74211963SAfshin.Ardakani@Sun.COM
74311963SAfshin.Ardakani@Sun.COM if (smb_string_decode(&path, arg->data, arg->datalen) != 0)
74411963SAfshin.Ardakani@Sun.COM return (SMB_DOP_DECODE_ERROR);
74511963SAfshin.Ardakani@Sun.COM
74611963SAfshin.Ardakani@Sun.COM if (smbd_vss_get_count(path.buf, &count) == 0)
74711963SAfshin.Ardakani@Sun.COM arg->rbuf = smb_common_encode(&count, xdr_uint32_t,
74811963SAfshin.Ardakani@Sun.COM &arg->rsize);
74911963SAfshin.Ardakani@Sun.COM
75011963SAfshin.Ardakani@Sun.COM xdr_free(smb_string_xdr, (char *)&path);
75111963SAfshin.Ardakani@Sun.COM
75211963SAfshin.Ardakani@Sun.COM if (arg->rbuf == NULL)
75311963SAfshin.Ardakani@Sun.COM return (SMB_DOP_ENCODE_ERROR);
75411963SAfshin.Ardakani@Sun.COM return (SMB_DOP_SUCCESS);
75511963SAfshin.Ardakani@Sun.COM }
7565331Samw
75711963SAfshin.Ardakani@Sun.COM /*
75811963SAfshin.Ardakani@Sun.COM * Return the count and list of snapshots.
75911963SAfshin.Ardakani@Sun.COM * The list is in @GMT token format.
76011963SAfshin.Ardakani@Sun.COM */
76111963SAfshin.Ardakani@Sun.COM static int
smbd_dop_vss_get_snapshots(smbd_arg_t * arg)76211963SAfshin.Ardakani@Sun.COM smbd_dop_vss_get_snapshots(smbd_arg_t *arg)
76311963SAfshin.Ardakani@Sun.COM {
76411963SAfshin.Ardakani@Sun.COM char **gmtp;
76511963SAfshin.Ardakani@Sun.COM smb_gmttoken_query_t request;
76611963SAfshin.Ardakani@Sun.COM smb_gmttoken_response_t reply;
76711963SAfshin.Ardakani@Sun.COM uint_t i;
76811963SAfshin.Ardakani@Sun.COM
76911963SAfshin.Ardakani@Sun.COM bzero(&request, sizeof (smb_gmttoken_query_t));
77011963SAfshin.Ardakani@Sun.COM bzero(&reply, sizeof (smb_gmttoken_response_t));
77111963SAfshin.Ardakani@Sun.COM
77211963SAfshin.Ardakani@Sun.COM if (smb_common_decode(arg->data, arg->datalen,
77311963SAfshin.Ardakani@Sun.COM smb_gmttoken_query_xdr, &request) != 0)
77411963SAfshin.Ardakani@Sun.COM return (SMB_DOP_DECODE_ERROR);
77511963SAfshin.Ardakani@Sun.COM
77611963SAfshin.Ardakani@Sun.COM reply.gtr_gmttokens.gtr_gmttokens_val = malloc(request.gtq_count *
77711963SAfshin.Ardakani@Sun.COM sizeof (char *));
77811963SAfshin.Ardakani@Sun.COM bzero(reply.gtr_gmttokens.gtr_gmttokens_val, request.gtq_count *
77911963SAfshin.Ardakani@Sun.COM sizeof (char *));
78011963SAfshin.Ardakani@Sun.COM
78111963SAfshin.Ardakani@Sun.COM if (reply.gtr_gmttokens.gtr_gmttokens_val == NULL) {
78211963SAfshin.Ardakani@Sun.COM xdr_free(smb_gmttoken_query_xdr, (char *)&request);
78311963SAfshin.Ardakani@Sun.COM return (SMB_DOP_EMPTYBUF);
78411963SAfshin.Ardakani@Sun.COM }
78511963SAfshin.Ardakani@Sun.COM
78611963SAfshin.Ardakani@Sun.COM smbd_vss_get_snapshots(request.gtq_path, request.gtq_count,
78711963SAfshin.Ardakani@Sun.COM &reply.gtr_count,
78811963SAfshin.Ardakani@Sun.COM &reply.gtr_gmttokens.gtr_gmttokens_len,
78911963SAfshin.Ardakani@Sun.COM reply.gtr_gmttokens.gtr_gmttokens_val);
79011963SAfshin.Ardakani@Sun.COM
79111963SAfshin.Ardakani@Sun.COM arg->rbuf = smb_common_encode(&reply, smb_gmttoken_response_xdr,
79211963SAfshin.Ardakani@Sun.COM &arg->rsize);
79311963SAfshin.Ardakani@Sun.COM if (arg->rbuf == NULL) {
79411963SAfshin.Ardakani@Sun.COM xdr_free(smb_gmttoken_query_xdr, (char *)&request);
79511963SAfshin.Ardakani@Sun.COM return (SMB_DOP_ENCODE_ERROR);
79611963SAfshin.Ardakani@Sun.COM }
79711963SAfshin.Ardakani@Sun.COM
79811963SAfshin.Ardakani@Sun.COM for (i = 0, gmtp = reply.gtr_gmttokens.gtr_gmttokens_val;
79911963SAfshin.Ardakani@Sun.COM (i < request.gtq_count); i++) {
80011963SAfshin.Ardakani@Sun.COM if (*gmtp)
80111963SAfshin.Ardakani@Sun.COM free(*gmtp);
80211963SAfshin.Ardakani@Sun.COM gmtp++;
80311963SAfshin.Ardakani@Sun.COM }
80411963SAfshin.Ardakani@Sun.COM
80511963SAfshin.Ardakani@Sun.COM free(reply.gtr_gmttokens.gtr_gmttokens_val);
80611963SAfshin.Ardakani@Sun.COM xdr_free(smb_gmttoken_query_xdr, (char *)&request);
80711963SAfshin.Ardakani@Sun.COM return (SMB_DOP_SUCCESS);
80811963SAfshin.Ardakani@Sun.COM }
80911963SAfshin.Ardakani@Sun.COM
81011963SAfshin.Ardakani@Sun.COM /*
81111963SAfshin.Ardakani@Sun.COM * Return the name of the snapshot that matches the dataset path
81211963SAfshin.Ardakani@Sun.COM * and @GMT token.
81311963SAfshin.Ardakani@Sun.COM */
81411963SAfshin.Ardakani@Sun.COM static int
smbd_dop_vss_map_gmttoken(smbd_arg_t * arg)81511963SAfshin.Ardakani@Sun.COM smbd_dop_vss_map_gmttoken(smbd_arg_t *arg)
81611963SAfshin.Ardakani@Sun.COM {
81711963SAfshin.Ardakani@Sun.COM char *snapname;
81811963SAfshin.Ardakani@Sun.COM smb_gmttoken_snapname_t request;
81911963SAfshin.Ardakani@Sun.COM
82011963SAfshin.Ardakani@Sun.COM bzero(&request, sizeof (smb_gmttoken_snapname_t));
82111963SAfshin.Ardakani@Sun.COM
82211963SAfshin.Ardakani@Sun.COM if (smb_common_decode(arg->data, arg->datalen,
82311963SAfshin.Ardakani@Sun.COM smb_gmttoken_snapname_xdr, &request) != 0) {
82411963SAfshin.Ardakani@Sun.COM xdr_free(smb_gmttoken_snapname_xdr, (char *)&request);
82511963SAfshin.Ardakani@Sun.COM return (SMB_DOP_DECODE_ERROR);
82611963SAfshin.Ardakani@Sun.COM }
82711963SAfshin.Ardakani@Sun.COM
82811963SAfshin.Ardakani@Sun.COM if ((snapname = malloc(MAXPATHLEN)) == NULL) {
82911963SAfshin.Ardakani@Sun.COM xdr_free(smb_gmttoken_snapname_xdr, (char *)&request);
8305331Samw return (NULL);
8315331Samw }
8325331Samw
83311963SAfshin.Ardakani@Sun.COM if ((smbd_vss_map_gmttoken(request.gts_path, request.gts_gmttoken,
83411963SAfshin.Ardakani@Sun.COM snapname) != 0)) {
83511963SAfshin.Ardakani@Sun.COM *snapname = '\0';
83611963SAfshin.Ardakani@Sun.COM }
83711963SAfshin.Ardakani@Sun.COM
83811963SAfshin.Ardakani@Sun.COM arg->rbuf = smb_string_encode(snapname, &arg->rsize);
83911963SAfshin.Ardakani@Sun.COM xdr_free(smb_gmttoken_snapname_xdr, (char *)&request);
84011963SAfshin.Ardakani@Sun.COM free(snapname);
84111963SAfshin.Ardakani@Sun.COM
84211963SAfshin.Ardakani@Sun.COM if (arg->rbuf == NULL)
84311963SAfshin.Ardakani@Sun.COM return (SMB_DOP_ENCODE_ERROR);
84411963SAfshin.Ardakani@Sun.COM return (SMB_DOP_SUCCESS);
84511963SAfshin.Ardakani@Sun.COM }
84611963SAfshin.Ardakani@Sun.COM
84711963SAfshin.Ardakani@Sun.COM static int
smbd_dop_ads_find_host(smbd_arg_t * arg)84811963SAfshin.Ardakani@Sun.COM smbd_dop_ads_find_host(smbd_arg_t *arg)
84911963SAfshin.Ardakani@Sun.COM {
85011963SAfshin.Ardakani@Sun.COM smb_ads_host_info_t *hinfo = NULL;
85111963SAfshin.Ardakani@Sun.COM char *hostname = "";
85211963SAfshin.Ardakani@Sun.COM smb_string_t fqdn;
85311963SAfshin.Ardakani@Sun.COM
85411963SAfshin.Ardakani@Sun.COM bzero(&fqdn, sizeof (smb_string_t));
85511963SAfshin.Ardakani@Sun.COM
85611963SAfshin.Ardakani@Sun.COM if (smb_string_decode(&fqdn, arg->data, arg->datalen) != 0)
85711963SAfshin.Ardakani@Sun.COM return (SMB_DOP_DECODE_ERROR);
85811963SAfshin.Ardakani@Sun.COM
85911963SAfshin.Ardakani@Sun.COM if ((hinfo = smb_ads_find_host(fqdn.buf, NULL)) != NULL)
86011963SAfshin.Ardakani@Sun.COM hostname = hinfo->name;
86111963SAfshin.Ardakani@Sun.COM
86211963SAfshin.Ardakani@Sun.COM xdr_free(smb_string_xdr, (char *)&fqdn);
86311963SAfshin.Ardakani@Sun.COM
86411963SAfshin.Ardakani@Sun.COM arg->rbuf = smb_string_encode(hostname, &arg->rsize);
86511963SAfshin.Ardakani@Sun.COM free(hinfo);
86611963SAfshin.Ardakani@Sun.COM
86711963SAfshin.Ardakani@Sun.COM if (arg->rbuf == NULL)
86811963SAfshin.Ardakani@Sun.COM return (SMB_DOP_ENCODE_ERROR);
86911963SAfshin.Ardakani@Sun.COM return (SMB_DOP_SUCCESS);
8705331Samw }
8715331Samw
8725331Samw /*
87311963SAfshin.Ardakani@Sun.COM * Query the list of user/group quota entries for a given filesystem.
8745331Samw */
87511963SAfshin.Ardakani@Sun.COM static int
smbd_dop_quota_query(smbd_arg_t * arg)87611963SAfshin.Ardakani@Sun.COM smbd_dop_quota_query(smbd_arg_t *arg)
8775331Samw {
87811963SAfshin.Ardakani@Sun.COM smb_quota_query_t request;
87911963SAfshin.Ardakani@Sun.COM smb_quota_response_t reply;
88011963SAfshin.Ardakani@Sun.COM uint32_t status;
88111963SAfshin.Ardakani@Sun.COM
88211963SAfshin.Ardakani@Sun.COM bzero(&request, sizeof (smb_quota_query_t));
88311963SAfshin.Ardakani@Sun.COM bzero(&reply, sizeof (smb_quota_response_t));
88411963SAfshin.Ardakani@Sun.COM
88511963SAfshin.Ardakani@Sun.COM if (smb_common_decode(arg->data, arg->datalen,
88611963SAfshin.Ardakani@Sun.COM smb_quota_query_xdr, &request) != 0)
88711963SAfshin.Ardakani@Sun.COM return (SMB_DOP_DECODE_ERROR);
88811963SAfshin.Ardakani@Sun.COM
88911963SAfshin.Ardakani@Sun.COM status = smb_quota_query(&request, &reply);
89011963SAfshin.Ardakani@Sun.COM reply.qr_status = status;
89111963SAfshin.Ardakani@Sun.COM
89211963SAfshin.Ardakani@Sun.COM arg->rbuf = smb_common_encode(&reply, smb_quota_response_xdr,
89311963SAfshin.Ardakani@Sun.COM &arg->rsize);
8945331Samw
89511963SAfshin.Ardakani@Sun.COM xdr_free(smb_quota_query_xdr, (char *)&request);
89611963SAfshin.Ardakani@Sun.COM smb_quota_free(&reply);
89711963SAfshin.Ardakani@Sun.COM
89811963SAfshin.Ardakani@Sun.COM if (arg->rbuf == NULL)
89911963SAfshin.Ardakani@Sun.COM return (SMB_DOP_ENCODE_ERROR);
90011963SAfshin.Ardakani@Sun.COM return (SMB_DOP_SUCCESS);
90111963SAfshin.Ardakani@Sun.COM }
90211963SAfshin.Ardakani@Sun.COM
90311963SAfshin.Ardakani@Sun.COM /*
90411963SAfshin.Ardakani@Sun.COM * Set a list of user/group quota entries for a given filesystem.
90511963SAfshin.Ardakani@Sun.COM */
90611963SAfshin.Ardakani@Sun.COM static int
smbd_dop_quota_set(smbd_arg_t * arg)90711963SAfshin.Ardakani@Sun.COM smbd_dop_quota_set(smbd_arg_t *arg)
90811963SAfshin.Ardakani@Sun.COM {
90911963SAfshin.Ardakani@Sun.COM smb_quota_set_t request;
91011963SAfshin.Ardakani@Sun.COM uint32_t status = 0;
91111963SAfshin.Ardakani@Sun.COM
91211963SAfshin.Ardakani@Sun.COM bzero(&request, sizeof (smb_quota_set_t));
9136771Sjb150015
91411963SAfshin.Ardakani@Sun.COM if (smb_common_decode(arg->data, arg->datalen,
91511963SAfshin.Ardakani@Sun.COM smb_quota_set_xdr, &request) != 0)
91611963SAfshin.Ardakani@Sun.COM return (SMB_DOP_DECODE_ERROR);
91711963SAfshin.Ardakani@Sun.COM
91811963SAfshin.Ardakani@Sun.COM status = smb_quota_set(&request);
91911963SAfshin.Ardakani@Sun.COM
92011963SAfshin.Ardakani@Sun.COM arg->rbuf = smb_common_encode(&status, xdr_uint32_t, &arg->rsize);
92111963SAfshin.Ardakani@Sun.COM xdr_free(smb_quota_set_xdr, (char *)&request);
92211963SAfshin.Ardakani@Sun.COM
92311963SAfshin.Ardakani@Sun.COM if (arg->rbuf == NULL)
92411963SAfshin.Ardakani@Sun.COM return (SMB_DOP_ENCODE_ERROR);
92511963SAfshin.Ardakani@Sun.COM return (SMB_DOP_SUCCESS);
92611963SAfshin.Ardakani@Sun.COM }
92711963SAfshin.Ardakani@Sun.COM
92811963SAfshin.Ardakani@Sun.COM static int
smbd_dop_dfs_get_referrals(smbd_arg_t * arg)92911963SAfshin.Ardakani@Sun.COM smbd_dop_dfs_get_referrals(smbd_arg_t *arg)
93011963SAfshin.Ardakani@Sun.COM {
93111963SAfshin.Ardakani@Sun.COM dfs_referral_query_t request;
93211963SAfshin.Ardakani@Sun.COM dfs_referral_response_t reply;
93311963SAfshin.Ardakani@Sun.COM
93411963SAfshin.Ardakani@Sun.COM bzero(&request, sizeof (request));
93511963SAfshin.Ardakani@Sun.COM bzero(&reply, sizeof (reply));
9365331Samw
93711963SAfshin.Ardakani@Sun.COM if (smb_common_decode(arg->data, arg->datalen,
93811963SAfshin.Ardakani@Sun.COM dfs_referral_query_xdr, &request) != 0)
93911963SAfshin.Ardakani@Sun.COM return (SMB_DOP_DECODE_ERROR);
94011963SAfshin.Ardakani@Sun.COM
94111963SAfshin.Ardakani@Sun.COM reply.rp_status = dfs_get_referrals((const char *)request.rq_path,
94211963SAfshin.Ardakani@Sun.COM request.rq_type, &reply.rp_referrals);
94311963SAfshin.Ardakani@Sun.COM
94411963SAfshin.Ardakani@Sun.COM if (reply.rp_status != ERROR_SUCCESS)
94511963SAfshin.Ardakani@Sun.COM bzero(&reply.rp_referrals, sizeof (dfs_info_t));
9465331Samw
94711963SAfshin.Ardakani@Sun.COM arg->rbuf = smb_common_encode(&reply, dfs_referral_response_xdr,
94811963SAfshin.Ardakani@Sun.COM &arg->rsize);
94911963SAfshin.Ardakani@Sun.COM
95011963SAfshin.Ardakani@Sun.COM if (reply.rp_status == ERROR_SUCCESS)
95111963SAfshin.Ardakani@Sun.COM dfs_info_free(&reply.rp_referrals);
9525331Samw
95311963SAfshin.Ardakani@Sun.COM xdr_free(dfs_referral_query_xdr, (char *)&request);
95411963SAfshin.Ardakani@Sun.COM
95511963SAfshin.Ardakani@Sun.COM if (arg->rbuf == NULL)
95611963SAfshin.Ardakani@Sun.COM return (SMB_DOP_ENCODE_ERROR);
95711963SAfshin.Ardakani@Sun.COM return (SMB_DOP_SUCCESS);
9585331Samw }
959*12508Samw@Sun.COM
960*12508Samw@Sun.COM static int
smbd_dop_shr_hostaccess(smbd_arg_t * arg)961*12508Samw@Sun.COM smbd_dop_shr_hostaccess(smbd_arg_t *arg)
962*12508Samw@Sun.COM {
963*12508Samw@Sun.COM smb_shr_hostaccess_query_t request;
964*12508Samw@Sun.COM uint32_t reply;
965*12508Samw@Sun.COM
966*12508Samw@Sun.COM bzero(&request, sizeof (request));
967*12508Samw@Sun.COM bzero(&reply, sizeof (reply));
968*12508Samw@Sun.COM
969*12508Samw@Sun.COM if (smb_common_decode(arg->data, arg->datalen,
970*12508Samw@Sun.COM smb_shr_hostaccess_query_xdr, &request) != 0)
971*12508Samw@Sun.COM return (SMB_DOP_DECODE_ERROR);
972*12508Samw@Sun.COM
973*12508Samw@Sun.COM reply = smb_shr_hostaccess(&request.shq_ipaddr, request.shq_none,
974*12508Samw@Sun.COM request.shq_ro, request.shq_rw, request.shq_flag);
975*12508Samw@Sun.COM
976*12508Samw@Sun.COM arg->rbuf = smb_common_encode(&reply, xdr_uint32_t, &arg->rsize);
977*12508Samw@Sun.COM
978*12508Samw@Sun.COM xdr_free(smb_shr_hostaccess_query_xdr, (char *)&request);
979*12508Samw@Sun.COM
980*12508Samw@Sun.COM if (arg->rbuf == NULL)
981*12508Samw@Sun.COM return (SMB_DOP_ENCODE_ERROR);
982*12508Samw@Sun.COM return (SMB_DOP_SUCCESS);
983*12508Samw@Sun.COM }
984*12508Samw@Sun.COM
985*12508Samw@Sun.COM static int
smbd_dop_shr_exec(smbd_arg_t * arg)986*12508Samw@Sun.COM smbd_dop_shr_exec(smbd_arg_t *arg)
987*12508Samw@Sun.COM {
988*12508Samw@Sun.COM smb_shr_execinfo_t request;
989*12508Samw@Sun.COM int reply;
990*12508Samw@Sun.COM
991*12508Samw@Sun.COM bzero(&request, sizeof (request));
992*12508Samw@Sun.COM bzero(&reply, sizeof (reply));
993*12508Samw@Sun.COM
994*12508Samw@Sun.COM if (smb_common_decode(arg->data, arg->datalen,
995*12508Samw@Sun.COM smb_shr_execinfo_xdr, &request) != 0)
996*12508Samw@Sun.COM return (SMB_DOP_DECODE_ERROR);
997*12508Samw@Sun.COM
998*12508Samw@Sun.COM reply = smb_shr_exec(&request);
999*12508Samw@Sun.COM
1000*12508Samw@Sun.COM if (reply != 0)
1001*12508Samw@Sun.COM syslog(LOG_NOTICE, "Failed to execute %s command",
1002*12508Samw@Sun.COM (request.e_type == SMB_EXEC_MAP) ? "map" : "unmap");
1003*12508Samw@Sun.COM
1004*12508Samw@Sun.COM arg->rbuf = smb_common_encode(&reply, xdr_int, &arg->rsize);
1005*12508Samw@Sun.COM
1006*12508Samw@Sun.COM xdr_free(smb_shr_execinfo_xdr, (char *)&request);
1007*12508Samw@Sun.COM
1008*12508Samw@Sun.COM if (arg->rbuf == NULL)
1009*12508Samw@Sun.COM return (SMB_DOP_ENCODE_ERROR);
1010*12508Samw@Sun.COM return (SMB_DOP_SUCCESS);
1011*12508Samw@Sun.COM }
1012