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 */
2112508Samw@Sun.COM
225331Samw /*
2312065SKeyur.Desai@Sun.COM * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
245331Samw */
255331Samw
2610966SJordan.Brown@Sun.COM #include <smbsrv/smb_kproto.h>
275331Samw #include <smbsrv/smb_fsops.h>
287052Samw #include <smbsrv/smb_share.h>
2910966SJordan.Brown@Sun.COM #include <smbsrv/string.h>
305331Samw #include <smbsrv/nmpipes.h>
315331Samw #include <smbsrv/mailslot.h>
325331Samw
335331Samw /*
345331Samw * count of bytes in server response packet
355331Samw * except parameters and data. Note that setup
365331Samw * word count is zero.
375331Samw */
385331Samw #define RESP_HEADER_LEN 24
395331Samw
405331Samw /*
419914Samw@Sun.COM * We started by using common functions for transaction/transaction2
425331Samw * and transaction_secondary/transaction2_secondary because they
435331Samw * are respectively so similar. However, it turned out to be a bad
445331Samw * idea because of quirky differences. Be sure if you modify one
455331Samw * of these four functions to check and see if the modification should
465331Samw * be applied to its peer.
475331Samw */
485331Samw
4911963SAfshin.Ardakani@Sun.COM static int smb_trans_ready(smb_xa_t *);
5011963SAfshin.Ardakani@Sun.COM static smb_sdrc_t smb_trans_dispatch(smb_request_t *, smb_xa_t *);
5111963SAfshin.Ardakani@Sun.COM static smb_sdrc_t smb_trans2_dispatch(smb_request_t *, smb_xa_t *);
525331Samw
536030Sjb150015 smb_sdrc_t
smb_pre_transaction(smb_request_t * sr)546139Sjb150015 smb_pre_transaction(smb_request_t *sr)
556139Sjb150015 {
566139Sjb150015 DTRACE_SMB_1(op__Transaction__start, smb_request_t *, sr);
576139Sjb150015 return (SDRC_SUCCESS);
586139Sjb150015 }
596139Sjb150015
606139Sjb150015 void
smb_post_transaction(smb_request_t * sr)616139Sjb150015 smb_post_transaction(smb_request_t *sr)
626139Sjb150015 {
636139Sjb150015 DTRACE_SMB_1(op__Transaction__done, smb_request_t *, sr);
646139Sjb150015 }
656139Sjb150015
666139Sjb150015 smb_sdrc_t
smb_com_transaction(smb_request_t * sr)676139Sjb150015 smb_com_transaction(smb_request_t *sr)
685331Samw {
695331Samw int rc;
705331Samw unsigned char msrcnt, suwcnt;
715331Samw uint16_t tpscnt, tdscnt, mprcnt, mdrcnt, flags;
725331Samw uint16_t pscnt, psoff, dscnt, dsoff;
735331Samw uint32_t timeo;
745331Samw struct smb_xa *xa;
755331Samw char *stn;
765331Samw int ready;
775331Samw
785331Samw rc = smbsr_decode_vwv(sr, SMB_TRANSHDR_ED_FMT,
795331Samw &tpscnt, &tdscnt, &mprcnt, &mdrcnt, &msrcnt, &flags,
805331Samw &timeo, &pscnt, &psoff, &dscnt, &dsoff, &suwcnt);
815331Samw
826030Sjb150015 if (rc != 0)
836139Sjb150015 return (SDRC_ERROR);
845331Samw
855331Samw xa = smb_xa_create(sr->session, sr, tpscnt, tdscnt, mprcnt, mdrcnt,
865331Samw msrcnt, suwcnt);
875331Samw if (xa == NULL) {
885772Sas200622 smbsr_error(sr, 0, ERRSRV, ERRnoroom);
896139Sjb150015 return (SDRC_ERROR);
905331Samw }
915331Samw
925331Samw /* Should be some alignment stuff here in SMB? */
935331Samw if (sr->smb_flg2 & SMB_FLAGS2_UNICODE) {
945331Samw rc = smbsr_decode_data(sr, "%.U", sr, &stn);
955331Samw } else {
965331Samw rc = smbsr_decode_data(sr, "%s", sr, &stn);
975331Samw }
985331Samw if (rc != 0) {
995331Samw smb_xa_rele(sr->session, xa);
1006139Sjb150015 return (SDRC_ERROR);
1015331Samw }
1025331Samw
10311963SAfshin.Ardakani@Sun.COM xa->xa_pipe_name = smb_mem_strdup(stn);
1045331Samw xa->smb_flags = flags;
1055331Samw xa->smb_timeout = timeo;
1065331Samw xa->req_disp_param = pscnt;
1075331Samw xa->req_disp_data = dscnt;
1085331Samw
1095331Samw if (MBC_SHADOW_CHAIN(&xa->req_setup_mb, &sr->smb_vwv,
1105331Samw sr->smb_vwv.chain_offset, suwcnt * 2)) {
1115331Samw smb_xa_rele(sr->session, xa);
1125772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
1136139Sjb150015 return (SDRC_ERROR);
1145331Samw }
1155331Samw if (MBC_SHADOW_CHAIN(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
1165331Samw smb_xa_rele(sr->session, xa);
1175772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
1186139Sjb150015 return (SDRC_ERROR);
1195331Samw }
1205331Samw if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
1215331Samw smb_xa_rele(sr->session, xa);
1225772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
1236139Sjb150015 return (SDRC_ERROR);
1245331Samw }
1255331Samw
1265331Samw ready = smb_trans_ready(xa);
1275331Samw
1285331Samw if (smb_xa_open(xa)) {
1295331Samw smb_xa_rele(sr->session, xa);
1305772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRsrverror);
1316139Sjb150015 return (SDRC_ERROR);
1325331Samw }
1335331Samw sr->r_xa = xa;
1345331Samw
1355331Samw if (!ready) {
1366030Sjb150015 rc = smbsr_encode_empty_result(sr);
1376139Sjb150015 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
1385331Samw }
1395331Samw
1405331Samw if (!smb_xa_complete(xa)) {
1415331Samw smb_xa_close(xa);
1425772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
1436139Sjb150015 return (SDRC_ERROR);
1445331Samw }
1455331Samw
1465331Samw return (smb_trans_dispatch(sr, xa));
1475331Samw }
1485331Samw
1496030Sjb150015 smb_sdrc_t
smb_pre_transaction_secondary(smb_request_t * sr)1506139Sjb150015 smb_pre_transaction_secondary(smb_request_t *sr)
1516139Sjb150015 {
1526139Sjb150015 DTRACE_SMB_1(op__TransactionSecondary__start, smb_request_t *, sr);
1536139Sjb150015 return (SDRC_SUCCESS);
1546139Sjb150015 }
1556139Sjb150015
1566139Sjb150015 void
smb_post_transaction_secondary(smb_request_t * sr)1576139Sjb150015 smb_post_transaction_secondary(smb_request_t *sr)
1586139Sjb150015 {
1596139Sjb150015 DTRACE_SMB_1(op__TransactionSecondary__done, smb_request_t *, sr);
1606139Sjb150015 }
1616139Sjb150015
1626139Sjb150015 smb_sdrc_t
smb_com_transaction_secondary(smb_request_t * sr)1636139Sjb150015 smb_com_transaction_secondary(smb_request_t *sr)
1645331Samw {
1655331Samw uint16_t tpscnt, tdscnt, pscnt, psdisp;
1665331Samw uint16_t dscnt, dsoff, dsdisp, psoff;
1675331Samw smb_xa_t *xa;
1685331Samw int rc;
1695331Samw
1705331Samw if ((xa = smbsr_lookup_xa(sr)) == 0) {
1715772Sas200622 smbsr_error(sr, 0, ERRSRV, ERRsrverror);
1726139Sjb150015 return (SDRC_ERROR);
1735331Samw }
1745331Samw
1755331Samw if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
1765331Samw if (smb_sign_check_secondary(sr, xa->reply_seqnum) != 0) {
1775772Sas200622 smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
1785331Samw ERRDOS, ERRnoaccess);
1796139Sjb150015 return (SDRC_ERROR);
1805331Samw }
1815331Samw }
1825331Samw
1835331Samw if (xa->smb_com != SMB_COM_TRANSACTION) {
1845331Samw return (SDRC_DROP_VC);
1855331Samw }
1865331Samw
1875331Samw rc = smbsr_decode_vwv(sr, SMB_TRANSSHDR_ED_FMT, &tpscnt, &tdscnt,
1885331Samw &pscnt, &psoff, &psdisp, &dscnt, &dsoff, &dsdisp);
1895331Samw
1906030Sjb150015 if (rc != 0)
1916139Sjb150015 return (SDRC_ERROR);
1925331Samw
1935331Samw mutex_enter(&xa->xa_mutex);
1945331Samw xa->smb_tpscnt = tpscnt; /* might have shrunk */
1955331Samw xa->smb_tdscnt = tdscnt; /* might have shrunk */
1965331Samw xa->req_disp_param = psdisp+pscnt;
1975331Samw xa->req_disp_data = dsdisp+dscnt;
1985331Samw
1995331Samw if (MBC_SHADOW_CHAIN(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
2005331Samw mutex_exit(&xa->xa_mutex);
2015331Samw smb_xa_close(xa);
2025772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
2036139Sjb150015 return (SDRC_ERROR);
2045331Samw }
2055331Samw if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
2065331Samw mutex_exit(&xa->xa_mutex);
2075331Samw smb_xa_close(xa);
2085772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
2096139Sjb150015 return (SDRC_ERROR);
2105331Samw }
2115331Samw mutex_exit(&xa->xa_mutex);
2125331Samw
2135331Samw if (!smb_trans_ready(xa))
2145331Samw return (SDRC_NO_REPLY);
2155331Samw
2165331Samw if (!smb_xa_complete(xa))
2175331Samw return (SDRC_NO_REPLY);
2185331Samw
2195331Samw return (smb_trans_dispatch(sr, xa));
2205331Samw }
2215331Samw
2226030Sjb150015 smb_sdrc_t
smb_pre_ioctl(smb_request_t * sr)2236139Sjb150015 smb_pre_ioctl(smb_request_t *sr)
2246139Sjb150015 {
2256139Sjb150015 DTRACE_SMB_1(op__Ioctl__start, smb_request_t *, sr);
2266139Sjb150015 return (SDRC_SUCCESS);
2276139Sjb150015 }
2286139Sjb150015
2296139Sjb150015 void
smb_post_ioctl(smb_request_t * sr)2306139Sjb150015 smb_post_ioctl(smb_request_t *sr)
2316139Sjb150015 {
2326139Sjb150015 DTRACE_SMB_1(op__Ioctl__done, smb_request_t *, sr);
2336139Sjb150015 }
2346139Sjb150015
2356139Sjb150015 smb_sdrc_t
smb_com_ioctl(smb_request_t * sr)2366139Sjb150015 smb_com_ioctl(smb_request_t *sr)
2375331Samw {
2385331Samw uint16_t fid, category, function, tpscnt, tdscnt, mprcnt;
2395331Samw uint16_t mdrcnt, pscnt, pdoff, dscnt, dsoff;
2405331Samw uint32_t timeout;
2415331Samw int rc;
2425331Samw
2435331Samw rc = smbsr_decode_vwv(sr, "wwwwwwwl2.wwww", &fid, &category, &function,
2445331Samw &tpscnt, &tdscnt, &mprcnt, &mdrcnt, &timeout, &pscnt,
2455331Samw &pdoff, &dscnt, &dsoff);
2465331Samw
2476030Sjb150015 if (rc != 0)
2486139Sjb150015 return (SDRC_ERROR);
2495331Samw
2506139Sjb150015 return (SDRC_NOT_IMPLEMENTED);
2515331Samw }
2525331Samw
2536139Sjb150015 smb_sdrc_t
smb_pre_transaction2(smb_request_t * sr)2546139Sjb150015 smb_pre_transaction2(smb_request_t *sr)
2555331Samw {
2566139Sjb150015 DTRACE_SMB_1(op__Transaction2__start, smb_request_t *, sr);
2576139Sjb150015 return (SDRC_SUCCESS);
2586139Sjb150015 }
2596139Sjb150015
2606139Sjb150015 void
smb_post_transaction2(smb_request_t * sr)2616139Sjb150015 smb_post_transaction2(smb_request_t *sr)
2626139Sjb150015 {
2636139Sjb150015 DTRACE_SMB_1(op__Transaction2__done, smb_request_t *, sr);
2645331Samw }
2655331Samw
2666030Sjb150015 smb_sdrc_t
smb_com_transaction2(struct smb_request * sr)2675331Samw smb_com_transaction2(struct smb_request *sr)
2685331Samw {
2695331Samw unsigned char msrcnt, suwcnt;
2705331Samw uint16_t tpscnt, tdscnt, mprcnt, mdrcnt, flags;
2715331Samw uint16_t pscnt, psoff, dscnt, dsoff;
2725331Samw uint32_t timeo;
2735331Samw smb_xa_t *xa;
2745331Samw int ready;
2755331Samw int rc;
2765331Samw
2775331Samw rc = smbsr_decode_vwv(sr, SMB_TRANSHDR_ED_FMT, &tpscnt, &tdscnt,
2785331Samw &mprcnt, &mdrcnt, &msrcnt, &flags, &timeo, &pscnt, &psoff, &dscnt,
2795331Samw &dsoff, &suwcnt);
2805331Samw
2816030Sjb150015 if (rc != 0)
2826139Sjb150015 return (SDRC_ERROR);
2835331Samw
2845331Samw xa = smb_xa_create(sr->session, sr, tpscnt, tdscnt, mprcnt, mdrcnt,
2855331Samw msrcnt, suwcnt);
2865331Samw if (xa == 0) {
2875772Sas200622 smbsr_error(sr, 0, ERRSRV, ERRnoroom);
2886139Sjb150015 return (SDRC_ERROR);
2895331Samw }
2905331Samw
2915331Samw xa->smb_flags = flags;
2925331Samw xa->smb_timeout = timeo;
2935331Samw xa->req_disp_param = pscnt;
2945331Samw xa->req_disp_data = dscnt;
2955331Samw
2965331Samw if (MBC_SHADOW_CHAIN(&xa->req_setup_mb, &sr->smb_vwv,
2975331Samw sr->smb_vwv.chain_offset, suwcnt*2)) {
2985331Samw smb_xa_rele(sr->session, xa);
2995772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
3006139Sjb150015 return (SDRC_ERROR);
3015331Samw }
3025331Samw if (MBC_SHADOW_CHAIN(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
3035331Samw smb_xa_rele(sr->session, xa);
3045772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
3056139Sjb150015 return (SDRC_ERROR);
3065331Samw }
3075331Samw if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
3085331Samw smb_xa_rele(sr->session, xa);
3095772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
3106139Sjb150015 return (SDRC_ERROR);
3115331Samw }
3125331Samw
3135331Samw ready = smb_trans_ready(xa);
3145331Samw
3155331Samw if (smb_xa_open(xa)) {
3165331Samw smb_xa_rele(sr->session, xa);
3175772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRsrverror);
3186139Sjb150015 return (SDRC_ERROR);
3195331Samw }
3205331Samw sr->r_xa = xa;
3215331Samw
3225331Samw if (!ready) {
3236030Sjb150015 rc = smbsr_encode_empty_result(sr);
3246139Sjb150015 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
3255331Samw }
3265331Samw
3275331Samw if (!smb_xa_complete(xa)) {
3285331Samw smb_xa_close(xa);
3295772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
3306139Sjb150015 return (SDRC_ERROR);
3315331Samw }
3325331Samw
3335331Samw return (smb_trans2_dispatch(sr, xa));
3345331Samw }
3355331Samw
3366030Sjb150015 smb_sdrc_t
smb_pre_transaction2_secondary(smb_request_t * sr)3376139Sjb150015 smb_pre_transaction2_secondary(smb_request_t *sr)
3386139Sjb150015 {
3396139Sjb150015 DTRACE_SMB_1(op__Transaction2Secondary__start, smb_request_t *, sr);
3406139Sjb150015 return (SDRC_SUCCESS);
3416139Sjb150015 }
3426139Sjb150015
3436139Sjb150015 void
smb_post_transaction2_secondary(smb_request_t * sr)3446139Sjb150015 smb_post_transaction2_secondary(smb_request_t *sr)
3456139Sjb150015 {
3466139Sjb150015 DTRACE_SMB_1(op__Transaction2Secondary__done, smb_request_t *, sr);
3476139Sjb150015 }
3486139Sjb150015
3496139Sjb150015 smb_sdrc_t
smb_com_transaction2_secondary(smb_request_t * sr)3506139Sjb150015 smb_com_transaction2_secondary(smb_request_t *sr)
3515331Samw {
3525331Samw uint16_t tpscnt, tdscnt, fid;
3535331Samw uint16_t pscnt, psoff, psdisp, dscnt, dsoff, dsdisp;
3545331Samw smb_xa_t *xa;
3555331Samw int rc;
3565331Samw
3575331Samw if ((xa = smbsr_lookup_xa(sr)) == 0) {
3585772Sas200622 smbsr_error(sr, 0, ERRSRV, ERRsrverror);
3596139Sjb150015 return (SDRC_ERROR);
3605331Samw }
3615331Samw
3625331Samw if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
3635331Samw if (smb_sign_check_secondary(sr, xa->reply_seqnum) != 0) {
3645772Sas200622 smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
3655331Samw ERRDOS, ERRnoaccess);
3666139Sjb150015 return (SDRC_ERROR);
3675331Samw }
3685331Samw }
3695331Samw
3705331Samw if (xa->smb_com != SMB_COM_TRANSACTION2) {
3715331Samw return (SDRC_DROP_VC);
3725331Samw }
3735331Samw
3745331Samw rc = smbsr_decode_vwv(sr, SMB_TRANS2SHDR_ED_FMT, &tpscnt, &tdscnt,
3755331Samw &pscnt, &psoff, &psdisp, &dscnt, &dsoff, &dsdisp, &fid);
3765331Samw
3776030Sjb150015 if (rc != 0)
3786139Sjb150015 return (SDRC_ERROR);
3795331Samw
3805331Samw mutex_enter(&xa->xa_mutex);
3815331Samw xa->smb_tpscnt = tpscnt; /* might have shrunk */
3825331Samw xa->smb_tdscnt = tdscnt; /* might have shrunk */
3835331Samw xa->xa_smb_fid = fid; /* overwrite rules? */
3845331Samw xa->req_disp_param = psdisp + pscnt;
3855331Samw xa->req_disp_data = dsdisp + dscnt;
3865331Samw
3875331Samw if (MBC_SHADOW_CHAIN(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
3885331Samw mutex_exit(&xa->xa_mutex);
3895331Samw smb_xa_close(xa);
3905772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
3916139Sjb150015 return (SDRC_ERROR);
3925331Samw }
3935331Samw if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
3945331Samw mutex_exit(&xa->xa_mutex);
3955331Samw smb_xa_close(xa);
3965772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
3976139Sjb150015 return (SDRC_ERROR);
3985331Samw }
3995331Samw mutex_exit(&xa->xa_mutex);
4005331Samw
4015331Samw if (!smb_trans_ready(xa))
4025331Samw return (SDRC_NO_REPLY);
4035331Samw
4045331Samw if (!smb_xa_complete(xa))
4055331Samw return (SDRC_NO_REPLY);
4065331Samw
4075331Samw return (smb_trans2_dispatch(sr, xa));
4085331Samw }
4095331Samw
4106030Sjb150015 static smb_sdrc_t
smb_nt_trans_dispatch(struct smb_request * sr,struct smb_xa * xa)4115331Samw smb_nt_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
4125331Samw {
4135331Samw int rc;
4145331Samw int total_bytes, n_setup, n_param, n_data;
4155331Samw int param_off, param_pad, data_off, data_pad;
4165331Samw
4175331Samw n_setup = (xa->smb_msrcnt < 200) ? xa->smb_msrcnt : 200;
4185331Samw n_setup++;
4195331Samw n_setup = n_setup & ~0x0001;
4205331Samw n_param = (xa->smb_mprcnt < smb_maxbufsize)
4215331Samw ? xa->smb_mprcnt : smb_maxbufsize;
4225331Samw n_param++;
4235331Samw n_param = n_param & ~0x0001;
4245331Samw rc = smb_maxbufsize - (SMBHEADERSIZE + 28 + n_setup + n_param);
4255331Samw n_data = (xa->smb_mdrcnt < rc) ? xa->smb_mdrcnt : rc;
4265331Samw MBC_INIT(&xa->rep_setup_mb, n_setup * 2);
4275331Samw MBC_INIT(&xa->rep_param_mb, n_param);
4285331Samw MBC_INIT(&xa->rep_data_mb, n_data);
4295331Samw
4305331Samw switch (xa->smb_func) {
4315331Samw case NT_TRANSACT_CREATE:
4326139Sjb150015 if ((rc = smb_pre_nt_transact_create(sr, xa)) == 0)
4336139Sjb150015 rc = smb_nt_transact_create(sr, xa);
4346139Sjb150015 smb_post_nt_transact_create(sr, xa);
4355331Samw break;
4365331Samw case NT_TRANSACT_NOTIFY_CHANGE:
4375331Samw rc = smb_nt_transact_notify_change(sr, xa);
4385331Samw break;
4395331Samw case NT_TRANSACT_QUERY_SECURITY_DESC:
4405331Samw rc = smb_nt_transact_query_security_info(sr, xa);
4415331Samw break;
4425331Samw case NT_TRANSACT_SET_SECURITY_DESC:
4435331Samw rc = smb_nt_transact_set_security_info(sr, xa);
4445331Samw break;
4455331Samw case NT_TRANSACT_IOCTL:
4465331Samw rc = smb_nt_transact_ioctl(sr, xa);
4475331Samw break;
4485331Samw case NT_TRANSACT_QUERY_QUOTA:
44911963SAfshin.Ardakani@Sun.COM rc = smb_nt_transact_query_quota(sr, xa);
4509914Samw@Sun.COM break;
4515331Samw case NT_TRANSACT_SET_QUOTA:
45211963SAfshin.Ardakani@Sun.COM rc = smb_nt_transact_set_quota(sr, xa);
45311963SAfshin.Ardakani@Sun.COM break;
45410966SJordan.Brown@Sun.COM case NT_TRANSACT_RENAME:
45510966SJordan.Brown@Sun.COM rc = smb_nt_transact_rename(sr, xa);
45610966SJordan.Brown@Sun.COM break;
45710966SJordan.Brown@Sun.COM
4585331Samw default:
4595772Sas200622 smbsr_error(sr, 0, ERRSRV, ERRsmbcmd);
4606139Sjb150015 return (SDRC_ERROR);
4615331Samw }
4625331Samw
4635331Samw switch (rc) {
4646139Sjb150015 case SDRC_SUCCESS:
4655331Samw break;
4665331Samw
4675331Samw case SDRC_DROP_VC:
4685331Samw case SDRC_NO_REPLY:
4696139Sjb150015 case SDRC_ERROR:
4708262SJose.Borrego@Sun.COM case SDRC_SR_KEPT:
4715331Samw return (rc);
4725331Samw
4736139Sjb150015 case SDRC_NOT_IMPLEMENTED:
4745772Sas200622 smbsr_error(sr, 0, ERRSRV, ERRsmbcmd);
4756139Sjb150015 return (SDRC_ERROR);
4765331Samw
4775331Samw default:
4785331Samw break;
4795331Samw }
4805331Samw
4815331Samw n_setup = MBC_LENGTH(&xa->rep_setup_mb);
4825331Samw n_param = MBC_LENGTH(&xa->rep_param_mb);
4835331Samw n_data = MBC_LENGTH(&xa->rep_data_mb);
4845331Samw
4855331Samw if (xa->smb_msrcnt < n_setup ||
4865331Samw xa->smb_mprcnt < n_param ||
4875331Samw xa->smb_mdrcnt < n_data) {
4885772Sas200622 smbsr_error(sr, 0, ERRSRV, ERRsmbcmd);
4896139Sjb150015 return (SDRC_ERROR);
4905331Samw }
4915331Samw
4925331Samw /* neato, blast it over there */
4935331Samw
4945331Samw n_setup = (n_setup + 1) / 2; /* Conver to setup words */
4955331Samw param_pad = 1; /* must be one */
4965331Samw param_off = param_pad + 32 + 37 + (n_setup << 1) + 2;
4975331Samw data_pad = (4 - ((param_off + n_param) & 3)) % 4; /* Pad to 4 byte */
4985331Samw data_off = param_off + n_param + data_pad; /* Param off from hdr */
4995331Samw total_bytes = param_pad + n_param + data_pad + n_data;
5005331Samw
5016030Sjb150015 rc = smbsr_encode_result(sr, 18+n_setup, total_bytes,
5027052Samw "b3.llllllllbCw#.C#.C",
5035331Samw 18 + n_setup, /* wct */
5045331Samw n_param, /* Total Parameter Bytes */
5055331Samw n_data, /* Total Data Bytes */
5065331Samw n_param, /* Total Parameter Bytes this buffer */
5075331Samw param_off, /* Param offset from header start */
5085331Samw 0, /* Param displacement */
5095331Samw n_data, /* Total Data Bytes this buffer */
5105331Samw data_off, /* Data offset from header start */
5115331Samw 0, /* Data displacement */
5125331Samw n_setup, /* suwcnt */
5135331Samw &xa->rep_setup_mb, /* setup[] */
5145331Samw total_bytes, /* Total data bytes */
5155331Samw param_pad,
5165331Samw &xa->rep_param_mb,
5175331Samw data_pad,
5185331Samw &xa->rep_data_mb);
5196139Sjb150015 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
5205331Samw }
5215331Samw
5226139Sjb150015 smb_sdrc_t
smb_pre_nt_transact(smb_request_t * sr)5236139Sjb150015 smb_pre_nt_transact(smb_request_t *sr)
5246139Sjb150015 {
5256139Sjb150015 DTRACE_SMB_1(op__NtTransact__start, smb_request_t *, sr);
5266139Sjb150015 return (SDRC_SUCCESS);
5276139Sjb150015 }
5286139Sjb150015
5296139Sjb150015 void
smb_post_nt_transact(smb_request_t * sr)5306139Sjb150015 smb_post_nt_transact(smb_request_t *sr)
5316139Sjb150015 {
5326139Sjb150015 DTRACE_SMB_1(op__NtTransact__done, smb_request_t *, sr);
5336139Sjb150015 }
5345331Samw
5356030Sjb150015 smb_sdrc_t
smb_com_nt_transact(struct smb_request * sr)5365331Samw smb_com_nt_transact(struct smb_request *sr)
5375331Samw {
5385331Samw uint16_t Function;
5395331Samw unsigned char MaxSetupCount, SetupCount;
5405331Samw uint32_t TotalParameterCount, TotalDataCount;
5415331Samw uint32_t MaxParameterCount, MaxDataCount, pscnt;
5425331Samw uint32_t psoff, dscnt, dsoff;
5435331Samw smb_xa_t *xa;
5445331Samw int ready;
5455331Samw int rc;
5465331Samw
5475331Samw rc = smbsr_decode_vwv(sr, SMB_NT_TRANSHDR_ED_FMT, &MaxSetupCount,
5485331Samw &TotalParameterCount, &TotalDataCount, &MaxParameterCount,
5495331Samw &MaxDataCount, &pscnt, &psoff, &dscnt,
5505331Samw &dsoff, &SetupCount, &Function);
5515331Samw
5526030Sjb150015 if (rc != 0)
5536139Sjb150015 return (SDRC_ERROR);
5545331Samw
5555331Samw xa = smb_xa_create(sr->session, sr, TotalParameterCount, TotalDataCount,
5565331Samw MaxParameterCount, MaxDataCount, MaxSetupCount, SetupCount);
5575331Samw if (xa == 0) {
5585772Sas200622 smbsr_error(sr, 0, ERRSRV, ERRnoroom);
5596139Sjb150015 return (SDRC_ERROR);
5605331Samw }
5615331Samw
5625331Samw xa->smb_flags = 0;
5635331Samw xa->smb_timeout = 0;
5645331Samw xa->smb_func = Function;
5655331Samw xa->req_disp_param = pscnt;
5665331Samw xa->req_disp_data = dscnt;
5675331Samw
5685331Samw if (MBC_SHADOW_CHAIN(&xa->req_setup_mb, &sr->smb_vwv,
5695331Samw sr->smb_vwv.chain_offset, SetupCount * 2)) {
5705331Samw smb_xa_rele(sr->session, xa);
5715772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
5726139Sjb150015 return (SDRC_ERROR);
5735331Samw }
5745331Samw if (MBC_SHADOW_CHAIN(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
5755331Samw smb_xa_rele(sr->session, xa);
5765772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
5776139Sjb150015 return (SDRC_ERROR);
5785331Samw }
5795331Samw if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
5805331Samw smb_xa_rele(sr->session, xa);
5815772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
5826139Sjb150015 return (SDRC_ERROR);
5835331Samw }
5845331Samw
5855331Samw ready = smb_trans_ready(xa);
5865331Samw
5875331Samw if (smb_xa_open(xa)) {
5885331Samw smb_xa_rele(sr->session, xa);
5895772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRsrverror);
5906139Sjb150015 return (SDRC_ERROR);
5915331Samw }
5925331Samw sr->r_xa = xa;
5935331Samw
5945331Samw if (!ready) {
5956030Sjb150015 rc = smbsr_encode_empty_result(sr);
5966139Sjb150015 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
5975331Samw }
5985331Samw
5995331Samw if (!smb_xa_complete(xa)) {
6005331Samw smb_xa_close(xa);
6015772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
6026139Sjb150015 return (SDRC_ERROR);
6035331Samw }
6045331Samw
6055331Samw return (smb_nt_trans_dispatch(sr, xa));
6065331Samw }
6075331Samw
6086139Sjb150015 smb_sdrc_t
smb_pre_nt_transact_secondary(smb_request_t * sr)6096139Sjb150015 smb_pre_nt_transact_secondary(smb_request_t *sr)
6106139Sjb150015 {
6116139Sjb150015 DTRACE_SMB_1(op__NtTransactSecondary__start, smb_request_t *, sr);
6126139Sjb150015 return (SDRC_SUCCESS);
6136139Sjb150015 }
6146139Sjb150015
6156139Sjb150015 void
smb_post_nt_transact_secondary(smb_request_t * sr)6166139Sjb150015 smb_post_nt_transact_secondary(smb_request_t *sr)
6176139Sjb150015 {
6186139Sjb150015 DTRACE_SMB_1(op__NtTransactSecondary__done, smb_request_t *, sr);
6196139Sjb150015 }
6205331Samw
6216030Sjb150015 smb_sdrc_t
smb_com_nt_transact_secondary(struct smb_request * sr)6225331Samw smb_com_nt_transact_secondary(struct smb_request *sr)
6235331Samw {
6245331Samw uint16_t tpscnt, tdscnt, fid;
6255331Samw uint16_t pscnt, psoff, psdisp, dscnt, dsoff, dsdisp;
6265331Samw smb_xa_t *xa;
6275331Samw int rc;
6285331Samw
6295331Samw if ((xa = smbsr_lookup_xa(sr)) == 0) {
6305772Sas200622 smbsr_error(sr, 0, ERRSRV, ERRsrverror);
6316139Sjb150015 return (SDRC_ERROR);
6325331Samw }
6335331Samw
6345331Samw if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
6355331Samw if (smb_sign_check_secondary(sr, xa->reply_seqnum) != 0) {
6365772Sas200622 smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
6375331Samw ERRDOS, ERRnoaccess);
6386139Sjb150015 return (SDRC_ERROR);
6395331Samw }
6405331Samw }
6415331Samw
6425331Samw if (xa->smb_com != SMB_COM_TRANSACTION2) {
6435331Samw return (SDRC_DROP_VC);
6445331Samw }
6455331Samw
6465331Samw rc = smbsr_decode_vwv(sr, SMB_TRANS2SHDR_ED_FMT, &tpscnt, &tdscnt,
6475331Samw &pscnt, &psoff, &psdisp, &dscnt, &dsoff, &dsdisp, &fid);
6485331Samw
6496030Sjb150015 if (rc != 0)
6506139Sjb150015 return (SDRC_ERROR);
6515331Samw
6525331Samw mutex_enter(&xa->xa_mutex);
6535331Samw xa->smb_tpscnt = tpscnt; /* might have shrunk */
6545331Samw xa->smb_tdscnt = tdscnt; /* might have shrunk */
6555331Samw xa->xa_smb_fid = fid; /* overwrite rules? */
6565331Samw xa->req_disp_param = psdisp+pscnt;
6575331Samw xa->req_disp_data = dsdisp+dscnt;
6585331Samw
6595331Samw if (MBC_SHADOW_CHAIN(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
6605331Samw mutex_exit(&xa->xa_mutex);
6615331Samw smb_xa_close(xa);
6625772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
6636139Sjb150015 return (SDRC_ERROR);
6645331Samw }
6655331Samw if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
6665331Samw mutex_exit(&xa->xa_mutex);
6675331Samw smb_xa_close(xa);
6685772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
6696139Sjb150015 return (SDRC_ERROR);
6705331Samw }
6715331Samw mutex_exit(&xa->xa_mutex);
6725331Samw
6735331Samw if (!smb_trans_ready(xa))
6745331Samw return (SDRC_NO_REPLY);
6755331Samw
6765331Samw if (!smb_xa_complete(xa))
6775331Samw return (SDRC_NO_REPLY);
6785331Samw
6795331Samw return (smb_nt_trans_dispatch(sr, xa));
6805331Samw }
6815331Samw
6826030Sjb150015 static int
smb_trans_ready(smb_xa_t * xa)68311963SAfshin.Ardakani@Sun.COM smb_trans_ready(smb_xa_t *xa)
6845331Samw {
6855331Samw int rc;
6865331Samw
6875331Samw mutex_enter(&xa->xa_mutex);
6885331Samw rc = xa->req_disp_data >= xa->smb_tdscnt &&
6895331Samw xa->req_disp_param >= xa->smb_tpscnt;
6905331Samw mutex_exit(&xa->xa_mutex);
6915331Samw
6925331Samw return (rc);
6935331Samw }
6945331Samw
6956771Sjb150015 static void
smb_encode_SHARE_INFO_1(struct mbuf_chain * output,struct mbuf_chain * text,char * oem_name,uint16_t type,char * comment)6966771Sjb150015 smb_encode_SHARE_INFO_1(struct mbuf_chain *output, struct mbuf_chain *text,
6976771Sjb150015 char *oem_name, uint16_t type, char *comment)
6985331Samw {
6997052Samw (void) smb_mbc_encodef(output, "13c.wl", oem_name,
7006771Sjb150015 type, MBC_LENGTH(text));
7015331Samw
7027052Samw (void) smb_mbc_encodef(text, "s", comment ? comment : "");
7035331Samw }
7045331Samw
7056771Sjb150015 static void
smb_encode_SHARE_INFO_2(struct mbuf_chain * output,struct mbuf_chain * text,smb_request_t * sr,char * oem_name,uint16_t type,char * comment,uint16_t access,char * path,char * password)7066771Sjb150015 smb_encode_SHARE_INFO_2(struct mbuf_chain *output, struct mbuf_chain *text,
7076771Sjb150015 smb_request_t *sr, char *oem_name, uint16_t type,
7086771Sjb150015 char *comment, uint16_t access, char *path, char *password)
7095331Samw {
7106771Sjb150015 unsigned char pword[9];
7115331Samw
7125331Samw bzero(pword, sizeof (pword));
7135331Samw (void) strncpy((char *)pword, password, sizeof (pword));
7146771Sjb150015 smb_encode_SHARE_INFO_1(output, text, oem_name, type, comment);
7157052Samw (void) smb_mbc_encodef(output, "wwwl9c.",
7165331Samw access,
7176139Sjb150015 sr->sr_cfg->skc_maxconnections,
7186139Sjb150015 smb_server_get_session_count(),
7195331Samw MBC_LENGTH(text),
7206771Sjb150015 pword);
7217052Samw (void) smb_mbc_encodef(text, "s", path);
7225331Samw }
7235331Samw
7245331Samw int
smb_trans_net_share_enum(struct smb_request * sr,struct smb_xa * xa)7255331Samw smb_trans_net_share_enum(struct smb_request *sr, struct smb_xa *xa)
7265331Samw {
7275331Samw /*
7285331Samw * Number of data bytes that will
7295331Samw * be sent in the current response
7305331Samw */
7315331Samw uint16_t data_scnt;
7325331Samw
7335331Samw /*
7345331Samw * Total number of data bytes that
7355331Samw * are sent till now. This is only
7365331Samw * used for calculating current data
7375331Samw * displacement
7385331Samw */
7395331Samw uint16_t tot_data_scnt;
7405331Samw
7415331Samw /*
7425331Samw * Number of parameter bytes should
7435331Samw * be sent for the current response.
7445331Samw * It is 8 for the 1st response and
7455331Samw * 0 for others
7465331Samw */
7475331Samw uint16_t param_scnt;
7485331Samw
7495331Samw /* number of setup and parameter bytes */
7505331Samw uint16_t n_setup, n_param;
7515331Samw
7525331Samw /* data and parameter displacement */
7535331Samw uint16_t data_disp, param_disp;
7545331Samw
7555331Samw /* parameter and data offset and pad */
7565331Samw int param_off, param_pad, data_off, data_pad;
7575331Samw
7585331Samw /*
7595331Samw * total bytes of parameters and data
7605331Samw * in the packet, plus the pad bytes.
7615331Samw */
7625331Samw int tot_packet_bytes;
7635331Samw
7646771Sjb150015 boolean_t first_resp;
7656771Sjb150015
7666771Sjb150015 char fmt[16];
7675331Samw struct mbuf_chain reply;
7685331Samw
7696771Sjb150015 uint16_t level;
7706771Sjb150015 uint16_t pkt_bufsize;
7716771Sjb150015 smb_enumshare_info_t esi;
7726771Sjb150015 char *sent_buf;
7736771Sjb150015
7746771Sjb150015 ASSERT(sr->uid_user);
7755331Samw
7765331Samw /*
7775331Samw * Initialize the mbuf chain of reply to zero. If it is not
7785331Samw * zero, code inside the while loop will try to free the chain.
7795331Samw */
7805331Samw bzero(&reply, sizeof (struct mbuf_chain));
7815331Samw
7827052Samw if (smb_mbc_decodef(&xa->req_param_mb, "ww", &level,
7836771Sjb150015 &esi.es_bufsize) != 0)
7846139Sjb150015 return (SDRC_NOT_IMPLEMENTED);
7855331Samw
7865331Samw if (level != 1) {
7876771Sjb150015 /*
7886771Sjb150015 * Only level 1 is valid for NetShareEnum
7896771Sjb150015 * None of the error codes in the spec are meaningful
7906771Sjb150015 * here. This error code is returned by Windows.
7916771Sjb150015 */
7927052Samw (void) smb_mbc_encodef(&xa->rep_param_mb, "wwww",
7936771Sjb150015 ERROR_INVALID_LEVEL, 0, 0, 0);
7946139Sjb150015 return (SDRC_SUCCESS);
7955331Samw }
7965331Samw
79712508Samw@Sun.COM esi.es_buf = smb_srm_zalloc(sr, esi.es_bufsize);
79812065SKeyur.Desai@Sun.COM esi.es_posix_uid = crgetuid(sr->uid_user->u_cred);
79912508Samw@Sun.COM smb_kshare_enum(&esi);
8005331Samw
8016771Sjb150015 /* client buffer size is not big enough to hold any shares */
8026771Sjb150015 if (esi.es_nsent == 0) {
8037052Samw (void) smb_mbc_encodef(&xa->rep_param_mb, "wwww",
8046771Sjb150015 ERROR_MORE_DATA, 0, esi.es_nsent, esi.es_ntotal);
8056771Sjb150015 return (SDRC_SUCCESS);
8065331Samw }
8075331Samw
8085331Samw /*
8095331Samw * The rep_setup_mb is already initialized in smb_trans_dispatch().
8105331Samw * Calling MBC_INIT() will initialized the structure and so the
8115331Samw * pointer to the mbuf chains will be lost. Therefore, we need
8125331Samw * to free the resources before calling MBC_INIT() again.
8135331Samw */
8146771Sjb150015 n_setup = 0; /* Setup count for NetShareEnum SMB is 0 */
8155331Samw m_freem(xa->rep_setup_mb.chain);
8165331Samw MBC_INIT(&xa->rep_setup_mb, n_setup * 2);
8175331Samw
8186771Sjb150015 n_param = 8;
8196771Sjb150015 pkt_bufsize = sr->session->smb_msg_size -
8206771Sjb150015 (SMB_HEADER_ED_LEN + RESP_HEADER_LEN + n_param);
8215331Samw
8226771Sjb150015 tot_data_scnt = 0;
8236771Sjb150015 sent_buf = esi.es_buf;
8246771Sjb150015 first_resp = B_TRUE;
8256771Sjb150015
8266771Sjb150015 while (tot_data_scnt < esi.es_datasize) {
8276771Sjb150015 data_scnt = esi.es_datasize - tot_data_scnt;
8286771Sjb150015 if (data_scnt > pkt_bufsize)
8296771Sjb150015 data_scnt = pkt_bufsize;
8305331Samw m_freem(xa->rep_data_mb.chain);
8316771Sjb150015 MBC_INIT(&xa->rep_data_mb, data_scnt);
8326771Sjb150015
8336771Sjb150015 (void) sprintf(fmt, "%dc", data_scnt);
8347052Samw (void) smb_mbc_encodef(&xa->rep_data_mb, fmt, sent_buf);
8356771Sjb150015
8366771Sjb150015 sent_buf += data_scnt;
8375331Samw tot_data_scnt += data_scnt;
8385331Samw
8395331Samw /* Only the 1st response packet contains parameters */
8405331Samw param_scnt = (first_resp) ? n_param : 0;
8415331Samw param_pad = 1; /* always one */
8425331Samw param_off = SMB_HEADER_ED_LEN + RESP_HEADER_LEN;
8435331Samw param_disp = (first_resp) ? 0 : n_param;
8445331Samw
8455331Samw m_freem(xa->rep_param_mb.chain);
8465331Samw MBC_INIT(&xa->rep_param_mb, param_scnt);
8476771Sjb150015
8485331Samw if (first_resp) {
8496771Sjb150015 first_resp = B_FALSE;
8507052Samw (void) smb_mbc_encodef(&xa->rep_param_mb, "wwww",
8516771Sjb150015 (esi.es_ntotal > esi.es_nsent)
8526771Sjb150015 ? ERROR_MORE_DATA : 0,
8536771Sjb150015 0, esi.es_nsent, esi.es_ntotal);
8545331Samw }
8555331Samw
8565331Samw data_pad = (param_off + n_param) & 1; /* Pad to short */
8575331Samw
8585331Samw /* data off from hdr start */
8595331Samw data_off = param_off + param_scnt + data_pad;
8605331Samw data_disp = tot_data_scnt - data_scnt;
8615331Samw tot_packet_bytes = param_pad + param_scnt + data_pad +
8625331Samw data_scnt;
8635331Samw
8645331Samw /*
8655331Samw * Calling MBC_INIT() will initialized the structure and so the
8665331Samw * pointer to the mbuf chains will be lost. Therefore, we need
8675331Samw * to free the resources if any before calling MBC_INIT().
8685331Samw */
8695331Samw m_freem(reply.chain);
8705331Samw MBC_INIT(&reply, SMB_HEADER_ED_LEN
8716771Sjb150015 + sizeof (uint8_t) /* word parameters count */
8726771Sjb150015 + 10*sizeof (uint16_t) /* word parameters */
8736771Sjb150015 + n_setup*sizeof (uint16_t) /* setup parameters */
8746771Sjb150015 + sizeof (uint16_t) /* total data byte count */
8755331Samw + tot_packet_bytes);
8765331Samw
8777052Samw (void) smb_mbc_encodef(&reply, SMB_HEADER_ED_FMT,
8785331Samw sr->first_smb_com,
8795331Samw sr->smb_rcls,
8805331Samw sr->smb_reh,
8815331Samw sr->smb_err,
8825331Samw sr->smb_flg | SMB_FLAGS_REPLY,
8835331Samw sr->smb_flg2,
8845331Samw sr->smb_pid_high,
8855331Samw sr->smb_sig,
8865331Samw sr->smb_tid,
8875331Samw sr->smb_pid,
8885331Samw sr->smb_uid,
8895331Samw sr->smb_mid);
8905331Samw
8917052Samw (void) smb_mbc_encodef(&reply,
8927052Samw "bww2.wwwwwwb.Cw#.C#.C",
8935331Samw 10 + n_setup, /* wct */
8945331Samw n_param, /* Total Parameter Bytes */
8956771Sjb150015 esi.es_datasize, /* Total Data Bytes */
8965331Samw param_scnt, /* Total Parameter Bytes this buffer */
8975331Samw param_off, /* Param offset from header start */
8985331Samw param_disp, /* Param displacement */
8995331Samw data_scnt, /* Total Data Bytes this buffer */
9005331Samw data_off, /* Data offset from header start */
9015331Samw data_disp, /* Data displacement */
9025331Samw n_setup, /* suwcnt */
9035331Samw &xa->rep_setup_mb, /* setup[] */
9045331Samw tot_packet_bytes, /* Total data bytes */
9055331Samw param_pad,
9065331Samw &xa->rep_param_mb,
9075331Samw data_pad,
9085331Samw &xa->rep_data_mb);
9095331Samw
9105331Samw if (sr->session->signing.flags & SMB_SIGNING_ENABLED)
9117961SNatalie.Li@Sun.COM smb_sign_reply(sr, &reply);
9125331Samw
9135331Samw (void) smb_session_send(sr->session, 0, &reply);
9145331Samw }
9155331Samw
9165331Samw return (SDRC_NO_REPLY);
9175331Samw }
9185331Samw
9195331Samw int
smb_trans_net_share_getinfo(smb_request_t * sr,struct smb_xa * xa)9206771Sjb150015 smb_trans_net_share_getinfo(smb_request_t *sr, struct smb_xa *xa)
9215331Samw {
9226771Sjb150015 uint16_t level, max_bytes, access;
9235331Samw struct mbuf_chain str_mb;
9245331Samw char *share;
9255331Samw char *password;
92612508Samw@Sun.COM smb_kshare_t *si;
9275331Samw
9287052Samw if (smb_mbc_decodef(&xa->req_param_mb, "%sww", sr,
9296771Sjb150015 &share, &level, &max_bytes) != 0)
9306139Sjb150015 return (SDRC_NOT_IMPLEMENTED);
9315331Samw
93212508Samw@Sun.COM si = smb_kshare_lookup(share);
93312508Samw@Sun.COM if ((si == NULL) || (si->shr_oemname == NULL)) {
9347052Samw (void) smb_mbc_encodef(&xa->rep_param_mb, "www",
9355331Samw NERR_NetNameNotFound, 0, 0);
93612508Samw@Sun.COM if (si)
93712508Samw@Sun.COM smb_kshare_release(si);
9386139Sjb150015 return (SDRC_SUCCESS);
9395331Samw }
9405331Samw
9416771Sjb150015 access = SHARE_ACCESS_ALL;
9425331Samw password = "";
9435331Samw
9445331Samw MBC_INIT(&str_mb, max_bytes);
9455331Samw
9465331Samw switch (level) {
9475331Samw case 0 :
94812508Samw@Sun.COM (void) smb_mbc_encodef(&xa->rep_data_mb, "13c",
94912508Samw@Sun.COM si->shr_oemname);
9505331Samw break;
9515331Samw
9525331Samw case 1 :
9536771Sjb150015 smb_encode_SHARE_INFO_1(&xa->rep_data_mb, &str_mb,
95412508Samw@Sun.COM si->shr_oemname, si->shr_type, si->shr_cmnt);
9555331Samw break;
9565331Samw
9575331Samw case 2 :
9586771Sjb150015 smb_encode_SHARE_INFO_2(&xa->rep_data_mb, &str_mb, sr,
95912508Samw@Sun.COM si->shr_oemname, si->shr_type, si->shr_cmnt, access,
96012508Samw@Sun.COM si->shr_path, password);
9616771Sjb150015 break;
9626771Sjb150015
9635331Samw default:
96412508Samw@Sun.COM smb_kshare_release(si);
9657052Samw (void) smb_mbc_encodef(&xa->rep_param_mb, "www",
9666771Sjb150015 ERROR_INVALID_LEVEL, 0, 0);
9675331Samw m_freem(str_mb.chain);
9686139Sjb150015 return (SDRC_NOT_IMPLEMENTED);
9695331Samw }
9705331Samw
97112508Samw@Sun.COM smb_kshare_release(si);
9727052Samw (void) smb_mbc_encodef(&xa->rep_param_mb, "www", NERR_Success,
9735331Samw -MBC_LENGTH(&xa->rep_data_mb),
9745331Samw MBC_LENGTH(&xa->rep_data_mb) + MBC_LENGTH(&str_mb));
9757052Samw (void) smb_mbc_encodef(&xa->rep_data_mb, "C", &str_mb);
9765331Samw m_freem(str_mb.chain);
9776139Sjb150015 return (SDRC_SUCCESS);
9785331Samw }
9795331Samw
9805331Samw int
smb_trans_net_workstation_getinfo(struct smb_request * sr,struct smb_xa * xa)9816771Sjb150015 smb_trans_net_workstation_getinfo(struct smb_request *sr, struct smb_xa *xa)
9825331Samw {
9836771Sjb150015 uint16_t level, max_bytes;
9845331Samw struct mbuf_chain str_mb;
9855331Samw char *domain;
9865331Samw char *hostname;
9875331Samw
9887052Samw if ((smb_mbc_decodef(&xa->req_param_mb, "ww",
9896771Sjb150015 &level, &max_bytes) != 0) ||
9905331Samw (level != 10)) {
9917052Samw (void) smb_mbc_encodef(&xa->rep_param_mb, "wwww",
9925331Samw NERR_BadTransactConfig, 0, 0, 0);
9936139Sjb150015 return (SDRC_SUCCESS);
9945331Samw }
9955331Samw
9967961SNatalie.Li@Sun.COM domain = sr->sr_cfg->skc_nbdomain;
9976139Sjb150015 hostname = sr->sr_cfg->skc_hostname;
9985331Samw
9995331Samw MBC_INIT(&str_mb, max_bytes);
10005331Samw
10017052Samw (void) smb_mbc_encodef(&str_mb, "."); /* Prevent NULL pointers */
10025331Samw
10037052Samw (void) smb_mbc_encodef(&xa->rep_data_mb, "l", MBC_LENGTH(&str_mb));
10047052Samw (void) smb_mbc_encodef(&str_mb, "s", hostname);
10057052Samw (void) smb_mbc_encodef(&xa->rep_data_mb, "l", MBC_LENGTH(&str_mb));
10067052Samw (void) smb_mbc_encodef(&str_mb, "s", "nobody");
10077052Samw (void) smb_mbc_encodef(&xa->rep_data_mb, "l", MBC_LENGTH(&str_mb));
10087052Samw (void) smb_mbc_encodef(&str_mb, "s", domain);
10097052Samw (void) smb_mbc_encodef(&xa->rep_data_mb, "bbl",
1010*13082SJoyce.McIntosh@Sun.COM (uint8_t)sr->sr_cfg->skc_version.sv_major,
1011*13082SJoyce.McIntosh@Sun.COM (uint8_t)sr->sr_cfg->skc_version.sv_minor,
101211963SAfshin.Ardakani@Sun.COM MBC_LENGTH(&str_mb));
10137052Samw (void) smb_mbc_encodef(&str_mb, "s", domain);
10147052Samw (void) smb_mbc_encodef(&xa->rep_data_mb, "l", MBC_LENGTH(&str_mb));
10157052Samw (void) smb_mbc_encodef(&str_mb, "s", domain);
10165331Samw
10177052Samw (void) smb_mbc_encodef(&xa->rep_param_mb, "www", 0,
10185331Samw -MBC_LENGTH(&xa->rep_data_mb),
10195331Samw MBC_LENGTH(&xa->rep_data_mb) + MBC_LENGTH(&str_mb));
10207052Samw (void) smb_mbc_encodef(&xa->rep_data_mb, "C", &str_mb);
10215331Samw m_freem(str_mb.chain);
10226139Sjb150015 return (SDRC_SUCCESS);
10235331Samw }
10245331Samw
10255331Samw int
smb_trans_net_user_getinfo(struct smb_request * sr,struct smb_xa * xa)10266771Sjb150015 smb_trans_net_user_getinfo(struct smb_request *sr, struct smb_xa *xa)
10275331Samw {
10286771Sjb150015 uint16_t level, max_bytes;
10295331Samw unsigned char *user;
10305331Samw int rc;
10315331Samw
10327052Samw rc = smb_mbc_decodef(&xa->req_param_mb, "%sww", sr,
10335331Samw &user,
10345331Samw &level,
10355331Samw &max_bytes);
10365331Samw
10375331Samw if (rc != 0)
10386139Sjb150015 return (SDRC_NOT_IMPLEMENTED);
10395331Samw
10407052Samw (void) smb_mbc_encodef(&xa->rep_param_mb, "www",
10415331Samw NERR_UserNotFound, 0, 0);
10426139Sjb150015 return (SDRC_SUCCESS);
10435331Samw }
10445331Samw
10456030Sjb150015 smb_sdrc_t
smb_trans_net_server_getinfo(struct smb_request * sr,struct smb_xa * xa)10466771Sjb150015 smb_trans_net_server_getinfo(struct smb_request *sr, struct smb_xa *xa)
10475331Samw {
10486771Sjb150015 uint16_t level, buf_size;
10496771Sjb150015 uint16_t avail_data, max_data;
10505331Samw char server_name[16];
10515331Samw struct mbuf_chain str_mb;
10525331Samw
10537052Samw if (smb_mbc_decodef(&xa->req_param_mb, "ww", &level, &buf_size) != 0)
10546139Sjb150015 return (SDRC_ERROR);
10555331Samw
10566771Sjb150015 max_data = MBC_MAXBYTES(&xa->rep_data_mb);
10575331Samw
10585331Samw MBC_INIT(&str_mb, buf_size);
10595331Samw
10605331Samw bzero(server_name, sizeof (server_name));
10616771Sjb150015 (void) strncpy(server_name, sr->sr_cfg->skc_hostname,
10626771Sjb150015 sizeof (server_name));
10635331Samw
10646771Sjb150015 /* valid levels are 0 and 1 */
10655331Samw switch (level) {
10665331Samw case 0:
10677052Samw (void) smb_mbc_encodef(&xa->rep_data_mb, "16c", server_name);
10685331Samw break;
10696771Sjb150015
10705331Samw case 1:
10717052Samw (void) smb_mbc_encodef(&str_mb, "s",
10726771Sjb150015 sr->sr_cfg->skc_system_comment);
10737052Samw (void) smb_mbc_encodef(&xa->rep_data_mb, "16cbbll", server_name,
1074*13082SJoyce.McIntosh@Sun.COM (uint8_t)sr->sr_cfg->skc_version.sv_major,
1075*13082SJoyce.McIntosh@Sun.COM (uint8_t)sr->sr_cfg->skc_version.sv_minor,
10766771Sjb150015 MY_SERVER_TYPE, max_data - MBC_LENGTH(&str_mb));
10775331Samw break;
10786771Sjb150015
10795331Samw default:
10807052Samw (void) smb_mbc_encodef(&xa->rep_param_mb, "www",
10816771Sjb150015 ERROR_INVALID_LEVEL, 0, 0);
10825331Samw m_freem(str_mb.chain);
10836771Sjb150015 return (SDRC_SUCCESS);
10845331Samw }
10855331Samw
10866771Sjb150015 avail_data = MBC_LENGTH(&xa->rep_data_mb) + MBC_LENGTH(&str_mb);
10877052Samw (void) smb_mbc_encodef(&xa->rep_param_mb, "www",
10886771Sjb150015 NERR_Success, max_data - avail_data, avail_data);
10897052Samw (void) smb_mbc_encodef(&xa->rep_data_mb, "C", &str_mb);
10905331Samw m_freem(str_mb.chain);
10916139Sjb150015 return (SDRC_SUCCESS);
10925331Samw }
10935331Samw
10945331Samw /*
10955331Samw * 6.4 The NetServerEnum2 RAP Service
10965331Samw *
10975331Samw * The NetServerEnum2 RAP service lists all computers of the specified type
10985331Samw * or types that are visible in the specified domains. It may also
10995331Samw * enumerate domains.
11005331Samw *
11015331Samw * The following definition uses the notation and terminology defined in
11025331Samw * the CIFS Remote Administration Protocol specification, which is required
11035331Samw * in order to make it well-defined. The definition is:
11045331Samw *
11055331Samw * uint16_t NetServerEnum2 (
11065331Samw * uint16_t sLevel,
11075331Samw * RCVBUF pbBuffer,
11085331Samw * RCVBUFLEN cbBuffer,
11095331Samw * ENTCOUNT pcEntriesRead,
11105331Samw * uint16_t *pcTotalAvail,
11115331Samw * uint32_t fServerType,
11125331Samw * char *pszDomain,
11135331Samw * );
11145331Samw *
11155331Samw * where:
11165331Samw *
11175331Samw * sLevel specifies the level of detail (0 or 1) requested.
11185331Samw *
11195331Samw * pbBuffer points to the buffer to receive the returned data. If the
11205331Samw * function is successful, the buffer contains a sequence of
11215331Samw * server_info_x structures, where x is 0 or 1, depending on the
11225331Samw * level of detail requested.
11235331Samw *
11245331Samw * cbBuffer specifies the size, in bytes, of the buffer pointed to by
11255331Samw * the pbBuffer parameter.
11265331Samw *
11275331Samw * pcEntriesRead points to a 16 bit variable that receives a count of
11285331Samw * the number of servers enumerated in the buffer. This count is
11295331Samw * valid only if NetServerEnum2 returns the NERR_Success or
11305331Samw * ERROR_MORE_DATA values.
11315331Samw *
11325331Samw * pcTotal Avail points to a 16 bit variable that receives a count of
11335331Samw * the total number of available entries. This count is valid only if
11345331Samw * NetServerEnum2 returns the NERR_Success or ERROR_MORE_DATA values.
11355331Samw *
11365331Samw * fServerType specifies the type or types of computers to enumerate.
11375331Samw * Computers that match at least one of the specified types are
11385331Samw * returned in the buffer. Possible values are defined in the request
11395331Samw * parameters section.
11405331Samw *
11415331Samw * pszDomain points to a null-terminated string that contains the
11425331Samw * name of the workgroup in which to enumerate computers of the
11435331Samw * specified type or types. If the pszDomain parameter is a null
11445331Samw * string or a null pointer, servers are enumerated for the current
11455331Samw * domain of the computer.
11465331Samw *
11475331Samw * 6.4.1 Transaction Request Parameters section
11485331Samw *
11495331Samw * The Transaction request parameters section in this instance contains:
11505331Samw * . The 16 bit function number for NetServerEnum2 which is 104.
11515331Samw * . The parameter descriptor string which is "WrLehDz".
11525331Samw * . The data descriptor string for the (returned) data which is "B16" for
11535331Samw * level detail 0 or "B16BBDz" for level detail 1.
11545331Samw * . The actual parameters as described by the parameter descriptor
11555331Samw * string.
11565331Samw *
11575331Samw * The parameters are:
11585331Samw * . A 16 bit integer with a value of 0 or 1 (corresponding to the "W" in
11595331Samw * the parameter descriptor string. This represents the level of detail
11605331Samw * the server is expected to return
11615331Samw * . A 16 bit integer that contains the size of the receive buffer.
11625331Samw * . A 32 bit integer that represents the type of servers the function
11635331Samw * should enumerate. The possible values may be any of the following or
11645331Samw * a combination of the following:
11655331Samw *
11665331Samw * SV_TYPE_WORKSTATION 0x00000001 All workstations
11675331Samw * SV_TYPE_SERVER 0x00000002 All servers
11685331Samw * SV_TYPE_SQLSERVER 0x00000004 Any server running with SQL
11695331Samw * server
11705331Samw * SV_TYPE_DOMAIN_CTRL 0x00000008 Primary domain controller
11715331Samw * SV_TYPE_DOMAIN_BAKCTRL 0x00000010 Backup domain controller
11725331Samw * SV_TYPE_TIME_SOURCE 0x00000020 Server running the timesource
11735331Samw * service
11745331Samw * SV_TYPE_AFP 0x00000040 Apple File Protocol servers
11755331Samw * SV_TYPE_NOVELL 0x00000080 Novell servers
11765331Samw * SV_TYPE_DOMAIN_MEMBER 0x00000100 Domain Member
11775331Samw * SV_TYPE_PRINTQ_SERVER 0x00000200 Server sharing print queue
11785331Samw * SV_TYPE_DIALIN_SERVER 0x00000400 Server running dialin service.
11795331Samw * SV_TYPE_XENIX_SERVER 0x00000800 Xenix server
11805331Samw * SV_TYPE_NT 0x00001000 NT server
11815331Samw * SV_TYPE_WFW 0x00002000 Server running Windows for
11825331Samw * Workgroups
11835331Samw * SV_TYPE_SERVER_NT 0x00008000 Windows NT non DC server
11845331Samw * SV_TYPE_POTENTIAL_BROWSER 0x00010000 Server that can run the browser
11855331Samw * service
11865331Samw * SV_TYPE_BACKUP_BROWSER 0x00020000 Backup browser server
11875331Samw * SV_TYPE_MASTER_BROWSER 0x00040000 Master browser server
11885331Samw * SV_TYPE_DOMAIN_MASTER 0x00080000 Domain Master Browser server
11895331Samw * SV_TYPE_LOCAL_LIST_ONLY 0x40000000 Enumerate only entries marked
11905331Samw * "local"
11915331Samw * SV_TYPE_DOMAIN_ENUM 0x80000000 Enumerate Domains. The pszDomain
11925331Samw * parameter must be NULL.
11935331Samw *
11945331Samw * . A null terminated ASCII string representing the pszDomain parameter
11955331Samw * described above
11965331Samw *
11975331Samw * 6.4.2 Transaction Request Data section
11985331Samw *
11995331Samw * There is no data or auxiliary data to send as part of the request.
12005331Samw *
12015331Samw * 6.4.3 Transaction Response Parameters section
12025331Samw *
12035331Samw * The transaction response parameters section consists of:
12045331Samw * . A 16 bit word indicating the return status. The possible values are:
12055331Samw *
12065331Samw * Code Value Description
12075331Samw * NERR_Success 0 No errors encountered
12085331Samw * ERROR_MORE_DATA 234 Additional data is available
12095331Samw * NERR_ServerNotStarted 2114 The RAP service on the remote computer
12105331Samw * is not running
12115331Samw * NERR_BadTransactConfig 2141 The server is not configured for
12125331Samw * transactions, IPC$ is not shared
12135331Samw *
12145331Samw * . A 16 bit "converter" word.
12155331Samw * . A 16 bit number representing the number of entries returned.
12165331Samw * . A 16 bit number representing the total number of available entries.
12175331Samw * If the supplied buffer is large enough, this will equal the number of
12185331Samw * entries returned.
12195331Samw *
12205331Samw * 6.4.4 Transaction Response Data section
12215331Samw *
12225331Samw * The return data section consists of a number of SERVER_INFO_1 structures.
12235331Samw * The number of such structures present is determined by the third entry
12245331Samw * (described above) in the return parameters section.
12255331Samw *
12265331Samw * At level detail 0, the Transaction response data section contains a
12275331Samw * number of SERVER_INFO_0 data structure. The number of such structures is
12285331Samw * equal to the 16 bit number returned by the server in the third parameter
12295331Samw * in the Transaction response parameter section. The SERVER_INFO_0 data
12305331Samw * structure is defined as:
12315331Samw *
12325331Samw * struct SERVER_INFO_0 {
12335331Samw * char sv0_name[16];
12345331Samw * };
12355331Samw *
12365331Samw * where:
12375331Samw *
12385331Samw * sv0_name is a null-terminated string that specifies the name of a
12395331Samw * computer or domain .
12405331Samw *
12415331Samw * At level detail 1, the Transaction response data section contains a
12425331Samw * number of SERVER_INFO_1 data structure. The number of such structures is
12435331Samw * equal to the 16 bit number returned by the server in the third parameter
12445331Samw * in the Transaction response parameter section. The SERVER_INFO_1 data
12455331Samw * structure is defined as:
12465331Samw *
12475331Samw * struct SERVER_INFO_1 {
12485331Samw * char sv1_name[16];
12495331Samw * char sv1_version_major;
12505331Samw * char sv1_version_minor;
12515331Samw * uint32_t sv1_type;
12525331Samw * char *sv1_comment_or_master_browser;
12535331Samw * };
12545331Samw *
12555331Samw * sv1_name contains a null-terminated string that specifies the name
12565331Samw * of a computer, or a domain name if SV_TYPE_DOMAIN_ENUM is set in
12575331Samw * sv1_type.
12585331Samw *
12595331Samw * sv1_version_major whatever was specified in the HostAnnouncement
12605331Samw * or DomainAnnouncement frame with which the entry was registered.
12615331Samw *
12625331Samw * sv1_version_minor whatever was specified in the HostAnnouncement
12635331Samw * or DomainAnnouncement frame with which the entry was registered.
12645331Samw *
12655331Samw * sv1_type specifies the type of software the computer is running.
12665331Samw * The member can be one or a combination of the values defined above
12675331Samw * in the Transaction request parameters section for fServerType.
12685331Samw *
12695331Samw *
12705331Samw * sv1_comment_or_master_browser points to a null-terminated string. If
12715331Samw * the sv1_type indicates that the entry is for a domain, this
12725331Samw * specifies the name of server running the domain master browser;
12735331Samw * otherwise, it specifies a comment describing the server. The comment
12745331Samw * can be a null string or the pointer may be a null pointer.
12755331Samw *
12765331Samw * In case there are multiple SERVER_INFO_1 data structures to
12775331Samw * return, the server may put all these fixed length structures in
12785331Samw * the return buffer, leave some space and then put all the variable
12795331Samw * length data (the actual value of the sv1_comment strings) at the
12805331Samw * end of the buffer.
12815331Samw *
12825331Samw * There is no auxiliary data to receive.
12835331Samw */
12845331Samw
12855331Samw int
smb_trans_net_server_enum2(struct smb_request * sr,struct smb_xa * xa)12865331Samw smb_trans_net_server_enum2(struct smb_request *sr, struct smb_xa *xa)
12875331Samw {
12885331Samw uint16_t opcode, level, max_bytes;
12895331Samw uint32_t server_type;
12905331Samw unsigned char *domain;
12915331Samw struct mbuf_chain str_mb;
12925331Samw char *hostname, *s;
12935331Samw smb_kmod_cfg_t *si;
12945331Samw
12957052Samw if (smb_mbc_decodef(&xa->req_param_mb,
12967052Samw "%wsswwls", sr, &opcode, &s, &s,
12975331Samw &level, &max_bytes, &server_type, &domain) != 0)
12986139Sjb150015 return (SDRC_NOT_IMPLEMENTED);
12995331Samw
13006139Sjb150015 si = sr->sr_cfg;
13015331Samw
130210966SJordan.Brown@Sun.COM if (smb_strcasecmp(si->skc_nbdomain, (char *)domain, 0) != 0) {
13037052Samw (void) smb_mbc_encodef(&xa->rep_param_mb, "wwww", 0, 0, 0, 0);
13046139Sjb150015 return (SDRC_SUCCESS);
13055331Samw }
13065331Samw
13075331Samw if ((server_type & MY_SERVER_TYPE) == 0) {
13087052Samw (void) smb_mbc_encodef(&xa->rep_param_mb, "wwww", 0, 0, 0, 0);
13096139Sjb150015 return (SDRC_SUCCESS);
13105331Samw }
13115331Samw
13125331Samw MBC_INIT(&str_mb, max_bytes);
13135331Samw
13145331Samw hostname = si->skc_hostname;
13155331Samw
13167052Samw (void) smb_mbc_encodef(&xa->rep_data_mb, "16c", hostname);
13175331Samw if (level == 1) {
13187052Samw (void) smb_mbc_encodef(&xa->rep_data_mb, "bbll",
1319*13082SJoyce.McIntosh@Sun.COM (uint8_t)sr->sr_cfg->skc_version.sv_major,
1320*13082SJoyce.McIntosh@Sun.COM (uint8_t)sr->sr_cfg->skc_version.sv_minor,
13215331Samw MY_SERVER_TYPE, MBC_LENGTH(&str_mb));
13227052Samw (void) smb_mbc_encodef(&str_mb, "s", si->skc_system_comment);
13235331Samw }
13245331Samw
13257052Samw (void) smb_mbc_encodef(&xa->rep_param_mb, "wwww", 0,
13265331Samw -MBC_LENGTH(&xa->rep_data_mb), 1, 1);
13277052Samw (void) smb_mbc_encodef(&xa->rep_data_mb, "m", str_mb.chain);
13286139Sjb150015 return (SDRC_SUCCESS);
13295331Samw }
13305331Samw
133110966SJordan.Brown@Sun.COM static boolean_t
is_supported_mailslot(const char * mailslot)133210966SJordan.Brown@Sun.COM is_supported_mailslot(const char *mailslot)
133310966SJordan.Brown@Sun.COM {
133410966SJordan.Brown@Sun.COM static char *mailslots[] = {
133510966SJordan.Brown@Sun.COM PIPE_LANMAN,
133610966SJordan.Brown@Sun.COM MAILSLOT_LANMAN,
133710966SJordan.Brown@Sun.COM MAILSLOT_BROWSE,
133810966SJordan.Brown@Sun.COM MAILSLOT_MSBROWSE
133910966SJordan.Brown@Sun.COM };
134010966SJordan.Brown@Sun.COM
134110966SJordan.Brown@Sun.COM int i;
134210966SJordan.Brown@Sun.COM
134310966SJordan.Brown@Sun.COM for (i = 0; i < sizeof (mailslots)/sizeof (mailslots[0]); ++i)
134410966SJordan.Brown@Sun.COM if (smb_strcasecmp(mailslot, mailslots[i], 0) == 0)
134510966SJordan.Brown@Sun.COM return (B_TRUE);
134610966SJordan.Brown@Sun.COM
134710966SJordan.Brown@Sun.COM return (B_FALSE);
134810966SJordan.Brown@Sun.COM }
134910966SJordan.Brown@Sun.COM
13505331Samw /*
135110966SJordan.Brown@Sun.COM * Currently, just return false if the pipe is \\PIPE\repl.
135210966SJordan.Brown@Sun.COM * Otherwise, return true.
13535331Samw */
135410966SJordan.Brown@Sun.COM static boolean_t
is_supported_pipe(const char * pname)135510966SJordan.Brown@Sun.COM is_supported_pipe(const char *pname)
13565331Samw {
135710966SJordan.Brown@Sun.COM if (smb_strcasecmp(pname, PIPE_REPL, 0) == 0)
135810966SJordan.Brown@Sun.COM return (B_FALSE);
13595331Samw
136010966SJordan.Brown@Sun.COM return (B_TRUE);
13615331Samw }
13625331Samw
13636030Sjb150015 static smb_sdrc_t
smb_trans_dispatch(smb_request_t * sr,smb_xa_t * xa)136411963SAfshin.Ardakani@Sun.COM smb_trans_dispatch(smb_request_t *sr, smb_xa_t *xa)
13655331Samw {
13665331Samw int rc, pos;
13675331Samw int total_bytes, n_setup, n_param, n_data;
13685331Samw int param_off, param_pad, data_off, data_pad;
13695331Samw uint16_t opcode;
13705331Samw uint16_t devstate;
13715331Samw char *req_fmt;
13725331Samw char *rep_fmt;
13738934SJose.Borrego@Sun.COM smb_vdb_t vdb;
13745331Samw
13755331Samw n_setup = (xa->smb_msrcnt < 200) ? xa->smb_msrcnt : 200;
13765331Samw n_setup++;
13775331Samw n_setup = n_setup & ~0x0001;
13785331Samw n_param = (xa->smb_mprcnt < smb_maxbufsize)
13795331Samw ? xa->smb_mprcnt : smb_maxbufsize;
13805331Samw n_param++;
13815331Samw n_param = n_param & ~0x0001;
13825331Samw rc = smb_maxbufsize - (SMBHEADERSIZE + 28 + n_setup + n_param);
13835331Samw n_data = (xa->smb_mdrcnt < rc) ? xa->smb_mdrcnt : rc;
13845331Samw MBC_INIT(&xa->rep_setup_mb, n_setup * 2);
13855331Samw MBC_INIT(&xa->rep_param_mb, n_param);
13865331Samw MBC_INIT(&xa->rep_data_mb, n_data);
13875331Samw
13885331Samw if (xa->smb_suwcnt > 0 && STYPE_ISIPC(sr->tid_tree->t_res_type)) {
13897052Samw rc = smb_mbc_decodef(&xa->req_setup_mb, "ww", &opcode,
13905331Samw &sr->smb_fid);
13915331Samw if (rc != 0)
13925331Samw goto trans_err_not_supported;
13935331Samw switch (opcode) {
13945331Samw case TRANS_SET_NMPIPE_STATE:
13957052Samw if ((rc = smb_mbc_decodef(&xa->req_param_mb, "w",
13965331Samw &devstate)) != 0)
13975331Samw goto trans_err_not_supported;
13985331Samw
13996139Sjb150015 rc = SDRC_SUCCESS;
14005331Samw break;
14015331Samw
14025331Samw case TRANS_TRANSACT_NMPIPE:
14038934SJose.Borrego@Sun.COM smbsr_lookup_file(sr);
14045331Samw if (sr->fid_ofile == NULL) {
14055772Sas200622 smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
14065331Samw ERRDOS, ERRbadfid);
14076139Sjb150015 return (SDRC_ERROR);
14085331Samw }
14095331Samw
14107052Samw rc = smb_mbc_decodef(&xa->req_data_mb, "#B",
14115331Samw xa->smb_tdscnt, &vdb);
14125331Samw if (rc != 0)
14135331Samw goto trans_err_not_supported;
14145331Samw
14158934SJose.Borrego@Sun.COM rc = smb_opipe_transact(sr, &vdb.vdb_uio);
14165331Samw break;
14175331Samw
14185331Samw case TRANS_WAIT_NMPIPE:
141910966SJordan.Brown@Sun.COM if (!is_supported_pipe(xa->xa_pipe_name)) {
14205772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRbadfile);
14216139Sjb150015 return (SDRC_ERROR);
14225331Samw }
14236139Sjb150015 rc = SDRC_SUCCESS;
14245331Samw break;
14255331Samw
14265331Samw default:
14275331Samw goto trans_err_not_supported;
14285331Samw }
14295331Samw } else {
143010966SJordan.Brown@Sun.COM if (!is_supported_mailslot(xa->xa_pipe_name))
14315331Samw goto trans_err_not_supported;
14325331Samw
14337052Samw if ((rc = smb_mbc_decodef(&xa->req_param_mb, "%wss", sr,
14345331Samw &opcode, &req_fmt, &rep_fmt)) != 0)
14355331Samw goto trans_err_not_supported;
14365331Samw
14375331Samw switch (opcode) {
14385331Samw case API_WshareEnum:
14395331Samw rc = smb_trans_net_share_enum(sr, xa);
14405331Samw break;
14415331Samw
14425331Samw case API_WshareGetInfo:
14436771Sjb150015 rc = smb_trans_net_share_getinfo(sr, xa);
14445331Samw break;
14455331Samw
14465331Samw case API_WserverGetInfo:
14476771Sjb150015 rc = smb_trans_net_server_getinfo(sr, xa);
14485331Samw break;
14495331Samw
14505331Samw case API_WUserGetInfo:
14516771Sjb150015 rc = smb_trans_net_user_getinfo(sr, xa);
14525331Samw break;
14535331Samw
14545331Samw case API_WWkstaGetInfo:
14556771Sjb150015 rc = smb_trans_net_workstation_getinfo(sr, xa);
14565331Samw break;
14575331Samw
14585331Samw case API_NetServerEnum2:
14595331Samw rc = smb_trans_net_server_enum2(sr, xa);
14605331Samw break;
14615331Samw
14625331Samw default:
14635331Samw goto trans_err_not_supported;
14645331Samw }
14655331Samw }
14665331Samw
14675331Samw switch (rc) {
14686139Sjb150015 case SDRC_SUCCESS:
14695331Samw break;
14705331Samw
14715331Samw case SDRC_DROP_VC:
14725331Samw case SDRC_NO_REPLY:
14736139Sjb150015 case SDRC_ERROR:
14745331Samw return (rc);
14755331Samw
14766139Sjb150015 case SDRC_NOT_IMPLEMENTED:
14775331Samw goto trans_err_not_supported;
14785331Samw
14795331Samw default:
14805331Samw break;
14815331Samw }
14825331Samw
14835331Samw n_setup = MBC_LENGTH(&xa->rep_setup_mb);
14845331Samw n_param = MBC_LENGTH(&xa->rep_param_mb);
14855331Samw n_data = MBC_LENGTH(&xa->rep_data_mb);
14865331Samw
14875331Samw if (xa->smb_msrcnt < n_setup ||
14885331Samw xa->smb_mprcnt < n_param ||
14895331Samw xa->smb_mdrcnt < n_data) {
14905331Samw goto trans_err_too_small;
14915331Samw }
14925331Samw
14935331Samw /* neato, blast it over there */
14945331Samw
14955331Samw n_setup = (n_setup + 1) / 2; /* Convert to setup words */
14965331Samw param_pad = 1; /* always one */
14975331Samw param_off = param_pad + 32 + 21 + (n_setup << 1) + 2;
14985331Samw data_pad = (param_off + n_param) & 1; /* Pad to short */
14995331Samw /* Param off from hdr start */
15005331Samw data_off = param_off + n_param + data_pad;
15015331Samw total_bytes = param_pad + n_param + data_pad + n_data;
15025331Samw
15036030Sjb150015 rc = smbsr_encode_result(sr, 10+n_setup, total_bytes,
15047052Samw "bww2.wwwwwwb.Cw#.C#.C",
15055331Samw 10 + n_setup, /* wct */
15065331Samw n_param, /* Total Parameter Bytes */
15075331Samw n_data, /* Total Data Bytes */
15085331Samw n_param, /* Total Parameter Bytes this buffer */
15095331Samw param_off, /* Param offset from header start */
15105331Samw 0, /* Param displacement */
15115331Samw n_data, /* Total Data Bytes this buffer */
15125331Samw data_off, /* Data offset from header start */
15135331Samw 0, /* Data displacement */
15145331Samw n_setup, /* suwcnt */
15155331Samw &xa->rep_setup_mb, /* setup[] */
15165331Samw total_bytes, /* Total data bytes */
15175331Samw param_pad,
15185331Samw &xa->rep_param_mb,
15195331Samw data_pad,
15205331Samw &xa->rep_data_mb);
15216139Sjb150015 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
15225331Samw
15235331Samw trans_err_too_small:
15245331Samw rc = NERR_BufTooSmall;
15255331Samw goto trans_err;
15265331Samw
15275331Samw trans_err_not_supported:
15285331Samw rc = ERROR_NOT_SUPPORTED;
15295331Samw goto trans_err;
15305331Samw
15315331Samw trans_err:
15325331Samw pos = MBC_LENGTH(&sr->reply) + 23;
15337052Samw rc = smbsr_encode_result(sr, 10, 4, "bww2.wwwwwwb.www",
15345331Samw 10, /* wct */
15355331Samw 4, 0, /* tpscnt tdscnt */
15365331Samw 4, pos, 0, /* pscnt psoff psdisp */
15375331Samw 0, 0, 0, /* dscnt dsoff dsdisp */
15385331Samw 0, /* suwcnt */
15395331Samw 4, /* bcc */
15405331Samw rc,
15415331Samw 0); /* converter word? */
15426139Sjb150015 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
15435331Samw }
15445331Samw
15456030Sjb150015 static smb_sdrc_t
smb_trans2_dispatch(smb_request_t * sr,smb_xa_t * xa)154611963SAfshin.Ardakani@Sun.COM smb_trans2_dispatch(smb_request_t *sr, smb_xa_t *xa)
15475331Samw {
15485331Samw int rc, pos;
15495331Samw int total_bytes, n_setup, n_param, n_data;
15505331Samw int param_off, param_pad, data_off, data_pad;
15515331Samw uint16_t opcode;
15525331Samw uint16_t nt_unknown_secret = 0x0100;
15535331Samw char *fmt;
15545331Samw
15555331Samw n_setup = (xa->smb_msrcnt < 200) ? xa->smb_msrcnt : 200;
15565331Samw n_setup++;
15575331Samw n_setup = n_setup & ~0x0001;
15585331Samw n_param = (xa->smb_mprcnt < smb_maxbufsize)
15595331Samw ? xa->smb_mprcnt : smb_maxbufsize;
15605331Samw n_param++;
15615331Samw n_param = n_param & ~0x0001;
15625331Samw rc = smb_maxbufsize - (SMBHEADERSIZE + 28 + n_setup + n_param);
15635331Samw n_data = (xa->smb_mdrcnt < rc) ? xa->smb_mdrcnt : rc;
15645331Samw MBC_INIT(&xa->rep_setup_mb, n_setup * 2);
15655331Samw MBC_INIT(&xa->rep_param_mb, n_param);
15665331Samw MBC_INIT(&xa->rep_data_mb, n_data);
15675331Samw
15687052Samw if (smb_mbc_decodef(&xa->req_setup_mb, "w", &opcode) != 0)
15695331Samw goto trans_err_not_supported;
15705331Samw
15715331Samw /*
15725331Samw * Save this for /proc to read later.
15735331Samw */
15745331Samw xa->smb_func = opcode;
15755331Samw
15765331Samw /* for now, only respond to the */
15775331Samw switch (opcode) {
15788934SJose.Borrego@Sun.COM case TRANS2_OPEN2:
15798934SJose.Borrego@Sun.COM rc = smb_com_trans2_open2(sr, xa);
15808934SJose.Borrego@Sun.COM break;
15818934SJose.Borrego@Sun.COM
15825331Samw case TRANS2_CREATE_DIRECTORY:
15835331Samw rc = smb_com_trans2_create_directory(sr, xa);
15845331Samw break;
15855331Samw
15865331Samw case TRANS2_FIND_FIRST2:
15875331Samw /*
15885331Samw * Should have enough room to send the response
15895331Samw * data back to client.
15905331Samw */
15915331Samw if (n_data == 0) {
15925772Sas200622 smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
15935331Samw ERRDOS, ERROR_BAD_LENGTH);
15946139Sjb150015 return (SDRC_ERROR);
15955331Samw }
15965331Samw rc = smb_com_trans2_find_first2(sr, xa);
15975331Samw break;
15985331Samw
15995331Samw case TRANS2_FIND_NEXT2:
16005331Samw /*
16015331Samw * Should have enough room to send the response
16025331Samw * data back to client.
16035331Samw */
16045331Samw if (n_data == 0) {
16055772Sas200622 smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
16065331Samw ERRDOS, ERROR_BAD_LENGTH);
16076139Sjb150015 return (SDRC_ERROR);
16085331Samw }
16095331Samw rc = smb_com_trans2_find_next2(sr, xa);
16105331Samw break;
16115331Samw
16125331Samw case TRANS2_QUERY_FS_INFORMATION:
16135331Samw /*
16145331Samw * Should have enough room to send the response
16155331Samw * data back to client.
16165331Samw */
16175331Samw if (n_data == 0) {
16185772Sas200622 smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
16195331Samw ERRDOS, ERROR_BAD_LENGTH);
16206139Sjb150015 return (SDRC_ERROR);
16215331Samw }
16225331Samw rc = smb_com_trans2_query_fs_information(sr, xa);
16235331Samw break;
16245331Samw
162511963SAfshin.Ardakani@Sun.COM case TRANS2_SET_FS_INFORMATION:
162611963SAfshin.Ardakani@Sun.COM rc = smb_com_trans2_set_fs_information(sr, xa);
162711963SAfshin.Ardakani@Sun.COM break;
162811963SAfshin.Ardakani@Sun.COM
16295331Samw case TRANS2_QUERY_PATH_INFORMATION:
16305331Samw /*
16315331Samw * Should have enough room to send the response
16325331Samw * data back to client.
16335331Samw */
16345331Samw if (n_data == 0) {
16355772Sas200622 smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
16365331Samw ERRDOS, ERROR_BAD_LENGTH);
16376139Sjb150015 return (SDRC_ERROR);
16385331Samw }
16395331Samw rc = smb_com_trans2_query_path_information(sr, xa);
16405331Samw break;
16415331Samw
16425331Samw case TRANS2_QUERY_FILE_INFORMATION:
16435331Samw /*
16445331Samw * Should have enough room to send the response
16455331Samw * data back to client.
16465331Samw */
16475331Samw if (n_data == 0) {
16485772Sas200622 smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
16495331Samw ERRDOS, ERROR_BAD_LENGTH);
16506139Sjb150015 return (SDRC_ERROR);
16515331Samw }
16525331Samw rc = smb_com_trans2_query_file_information(sr, xa);
16535331Samw break;
16545331Samw
16555331Samw case TRANS2_SET_PATH_INFORMATION:
16565331Samw rc = smb_com_trans2_set_path_information(sr, xa);
16575331Samw break;
16585331Samw
16595331Samw case TRANS2_SET_FILE_INFORMATION:
16605331Samw rc = smb_com_trans2_set_file_information(sr, xa);
16615331Samw break;
166211963SAfshin.Ardakani@Sun.COM
166311963SAfshin.Ardakani@Sun.COM case TRANS2_GET_DFS_REFERRAL:
166411963SAfshin.Ardakani@Sun.COM rc = smb_com_trans2_get_dfs_referral(sr, xa);
166511963SAfshin.Ardakani@Sun.COM break;
166611963SAfshin.Ardakani@Sun.COM
16675331Samw default:
16688934SJose.Borrego@Sun.COM (void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0);
16695331Samw goto trans_err_not_supported;
16705331Samw }
16715331Samw
16725331Samw switch (rc) {
16736139Sjb150015 case SDRC_SUCCESS:
16745331Samw break;
16755331Samw
16765331Samw case SDRC_DROP_VC:
16775331Samw case SDRC_NO_REPLY:
16786139Sjb150015 case SDRC_ERROR:
16795331Samw return (rc);
16805331Samw
16816139Sjb150015 case SDRC_NOT_IMPLEMENTED:
16825331Samw goto trans_err_not_supported;
16835331Samw
16845331Samw default:
16855331Samw break;
16865331Samw }
16875331Samw
16885331Samw n_setup = MBC_LENGTH(&xa->rep_setup_mb);
16895331Samw n_param = MBC_LENGTH(&xa->rep_param_mb);
16905331Samw n_data = MBC_LENGTH(&xa->rep_data_mb);
16915331Samw
16925331Samw if (xa->smb_msrcnt < n_setup ||
16935331Samw xa->smb_mprcnt < n_param ||
16945331Samw xa->smb_mdrcnt < n_data) {
16955331Samw goto trans_err_too_small;
16965331Samw }
16975331Samw
16985331Samw /* neato, blast it over there */
16995331Samw
17005331Samw n_setup = (n_setup + 1) / 2; /* Conver to setup words */
17015331Samw param_pad = 1; /* must be one */
17025331Samw param_off = param_pad + 32 + 21 + (n_setup << 1) + 2;
17035331Samw
17045331Samw /*
17055331Samw * Including the nt_unknown_secret value persuades netmon to
17065331Samw * display the correct data format for QueryPathInfo and
17075331Samw * QueryFileInfo.
17085331Samw */
17095331Samw if (opcode == TRANS2_QUERY_FILE_INFORMATION ||
17105331Samw opcode == TRANS2_QUERY_PATH_INFORMATION) {
17115331Samw data_pad = sizeof (uint16_t);
17125331Samw data_off = param_off + n_param + data_pad;
17137052Samw fmt = "bww2.wwwwwwb.Cw#.CwC";
17145331Samw nt_unknown_secret = 0x0100;
17155331Samw }
17165331Samw else
17175331Samw {
17185331Samw data_pad = (param_off + n_param) & 1; /* Pad to short */
17195331Samw /* Param off from hdr start */
17205331Samw data_off = param_off + n_param + data_pad;
17217052Samw fmt = "bww2.wwwwwwb.Cw#.C#.C";
17225331Samw /*LINTED E_ASSIGN_NARROW_CONV*/
17235331Samw nt_unknown_secret = data_pad;
17245331Samw }
17255331Samw
17265331Samw total_bytes = param_pad + n_param + data_pad + n_data;
17275331Samw
17286030Sjb150015 rc = smbsr_encode_result(sr, 10+n_setup, total_bytes,
17295331Samw fmt,
17305331Samw 10 + n_setup, /* wct */
17315331Samw n_param, /* Total Parameter Bytes */
17325331Samw n_data /* + data_pad */, /* Total Data Bytes */
17335331Samw n_param, /* Total Parameter Bytes this buffer */
17345331Samw param_off, /* Param offset from header start */
17355331Samw 0, /* Param displacement */
17365331Samw n_data /* + data_pad */, /* Total Data Bytes this buffer */
17375331Samw data_off, /* Data offset from header start */
17385331Samw 0, /* Data displacement */
17395331Samw n_setup, /* suwcnt */
17405331Samw &xa->rep_setup_mb, /* setup[] */
17415331Samw total_bytes, /* Total data bytes */
17425331Samw param_pad,
17435331Samw &xa->rep_param_mb,
17445331Samw nt_unknown_secret,
17455331Samw &xa->rep_data_mb);
17466139Sjb150015 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
17475331Samw
17485331Samw trans_err_too_small:
17495331Samw rc = NERR_BufTooSmall;
17505331Samw goto trans_err;
17515331Samw
17525331Samw trans_err_not_supported:
17535331Samw rc = ERROR_NOT_SUPPORTED;
17545331Samw goto trans_err;
17555331Samw
17565331Samw trans_err:
17575331Samw pos = MBC_LENGTH(&sr->reply) + 23;
17587052Samw rc = smbsr_encode_result(sr, 10, 4, "bww2.wwwwwwb.www",
17595331Samw 10, /* wct */
17605331Samw 4, 0, /* tpscnt tdscnt */
17615331Samw 4, pos, 0, /* pscnt psoff psdisp */
17625331Samw 0, 0, 0, /* dscnt dsoff dsdisp */
17635331Samw 0, /* suwcnt */
17645331Samw 4, /* bcc */
17655331Samw rc,
17665331Samw 0); /* converter word? */
17676139Sjb150015 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
17685331Samw }
17695331Samw
17705331Samw smb_xa_t *
smb_xa_create(smb_session_t * session,smb_request_t * sr,uint32_t total_parameter_count,uint32_t total_data_count,uint32_t max_parameter_count,uint32_t max_data_count,uint32_t max_setup_count,uint32_t setup_word_count)17715331Samw smb_xa_create(
17725331Samw smb_session_t *session,
17735331Samw smb_request_t *sr,
17745331Samw uint32_t total_parameter_count,
17755331Samw uint32_t total_data_count,
17765331Samw uint32_t max_parameter_count,
17775331Samw uint32_t max_data_count,
17785331Samw uint32_t max_setup_count,
17795331Samw uint32_t setup_word_count)
17805331Samw {
17815331Samw smb_xa_t *xa, *nxa;
17825331Samw smb_llist_t *xlist;
17835331Samw
178410966SJordan.Brown@Sun.COM xa = kmem_zalloc(sizeof (smb_xa_t), KM_SLEEP);
17855331Samw xa->xa_refcnt = 1;
17865331Samw xa->smb_com = sr->smb_com;
17875331Samw xa->smb_flg = sr->smb_flg;
17885331Samw xa->smb_flg2 = sr->smb_flg2;
17895331Samw xa->smb_tid = sr->smb_tid;
17905331Samw xa->smb_pid = sr->smb_pid;
17915331Samw xa->smb_uid = sr->smb_uid;
17925331Samw xa->xa_smb_mid = sr->smb_mid;
17935331Samw xa->reply_seqnum = sr->reply_seqnum;
17945331Samw xa->smb_tpscnt = total_parameter_count;
17955331Samw xa->smb_tdscnt = total_data_count;
17965331Samw xa->smb_mprcnt = max_parameter_count;
17975331Samw xa->smb_mdrcnt = max_data_count;
17985331Samw xa->smb_msrcnt = max_setup_count;
17995331Samw xa->smb_suwcnt = setup_word_count;
18005331Samw xa->xa_session = session;
18015331Samw xa->xa_magic = SMB_XA_MAGIC;
18025331Samw
18035331Samw /*
18045331Samw * The new xa structure is checked against the current list to see
18055331Samw * if it exists already.
18065331Samw */
18075331Samw xlist = &session->s_xa_list;
18085331Samw smb_llist_enter(xlist, RW_WRITER);
18095331Samw nxa = smb_llist_head(xlist);
18105331Samw while (nxa) {
18115331Samw ASSERT(nxa->xa_magic == SMB_XA_MAGIC);
18125331Samw if (nxa->xa_smb_mid == xa->xa_smb_mid &&
18135331Samw nxa->smb_pid == xa->smb_pid &&
18145331Samw !SMB_XA_CLOSED(nxa) &&
18155331Samw !(nxa->xa_flags & SMB_XA_FLAG_COMPLETE)) {
18165331Samw smb_llist_exit(xlist);
181710966SJordan.Brown@Sun.COM kmem_free(xa, sizeof (smb_xa_t));
18185331Samw return (NULL);
18195331Samw }
18205331Samw nxa = smb_llist_next(xlist, nxa);
18215331Samw }
18225331Samw smb_llist_insert_tail(xlist, xa);
18235331Samw smb_llist_exit(xlist);
18245331Samw return (xa);
18255331Samw }
18265331Samw
18275331Samw void
smb_xa_delete(smb_xa_t * xa)18285331Samw smb_xa_delete(smb_xa_t *xa)
18295331Samw {
18305331Samw ASSERT(xa->xa_refcnt == 0);
18315331Samw ASSERT(SMB_XA_CLOSED(xa));
18325331Samw
183310966SJordan.Brown@Sun.COM if (xa->xa_pipe_name)
183411963SAfshin.Ardakani@Sun.COM smb_mem_free(xa->xa_pipe_name);
18355331Samw
18365331Samw if (xa->rep_setup_mb.chain != NULL)
18375331Samw m_freem(xa->rep_setup_mb.chain);
18385331Samw if (xa->rep_param_mb.chain != NULL)
18395331Samw m_freem(xa->rep_param_mb.chain);
18405331Samw if (xa->rep_data_mb.chain != NULL)
18415331Samw m_freem(xa->rep_data_mb.chain);
18425331Samw
18435331Samw xa->xa_magic = (uint32_t)~SMB_XA_MAGIC;
184410966SJordan.Brown@Sun.COM kmem_free(xa, sizeof (smb_xa_t));
18455331Samw }
18465331Samw
18475331Samw smb_xa_t *
smb_xa_hold(smb_xa_t * xa)18485331Samw smb_xa_hold(smb_xa_t *xa)
18495331Samw {
18505331Samw mutex_enter(&xa->xa_mutex);
18515331Samw xa->xa_refcnt++;
18525331Samw ASSERT(xa->xa_refcnt);
18535331Samw mutex_exit(&xa->xa_mutex);
18545331Samw return (xa);
18555331Samw }
18565331Samw
18575331Samw void
smb_xa_rele(smb_session_t * session,smb_xa_t * xa)18585331Samw smb_xa_rele(smb_session_t *session, smb_xa_t *xa)
18595331Samw {
18605331Samw mutex_enter(&xa->xa_mutex);
18615331Samw ASSERT(xa->xa_refcnt);
18625331Samw xa->xa_refcnt--;
18635331Samw if (SMB_XA_CLOSED(xa) && (xa->xa_refcnt == 0)) {
18645331Samw mutex_exit(&xa->xa_mutex);
18655331Samw smb_llist_enter(&session->s_xa_list, RW_WRITER);
18665331Samw smb_llist_remove(&session->s_xa_list, xa);
18675331Samw smb_llist_exit(&session->s_xa_list);
18685331Samw smb_xa_delete(xa);
18695331Samw return;
18705331Samw }
18715331Samw mutex_exit(&xa->xa_mutex);
18725331Samw }
18735331Samw
18745331Samw int
smb_xa_open(smb_xa_t * xa)18755331Samw smb_xa_open(smb_xa_t *xa)
18765331Samw {
18775331Samw int rc;
18785331Samw
18795331Samw mutex_enter(&xa->xa_mutex);
18805331Samw
18815331Samw ASSERT((xa->xa_flags & SMB_XA_FLAG_OPEN) == 0);
18825331Samw
18835331Samw if ((xa->xa_flags & SMB_XA_FLAG_CLOSE) == 0) {
18845331Samw xa->xa_flags |= SMB_XA_FLAG_OPEN;
18855331Samw rc = 0;
18865331Samw } else {
18875331Samw rc = ERROR_INVALID_HANDLE;
18885331Samw }
18895331Samw
18905331Samw mutex_exit(&xa->xa_mutex);
18915331Samw
18925331Samw return (rc);
18935331Samw }
18945331Samw
18955331Samw void
smb_xa_close(smb_xa_t * xa)18965331Samw smb_xa_close(smb_xa_t *xa)
18975331Samw {
18985331Samw mutex_enter(&xa->xa_mutex);
18995331Samw xa->xa_flags |= SMB_XA_FLAG_CLOSE;
19005331Samw xa->xa_flags &= ~SMB_XA_FLAG_OPEN;
19015331Samw
19025331Samw if (xa->xa_refcnt == 0) {
19035331Samw mutex_exit(&xa->xa_mutex);
19045331Samw smb_llist_enter(&xa->xa_session->s_xa_list, RW_WRITER);
19055331Samw smb_llist_remove(&xa->xa_session->s_xa_list, xa);
19065331Samw smb_llist_exit(&xa->xa_session->s_xa_list);
19075331Samw smb_xa_delete(xa);
19085331Samw return;
19095331Samw }
19105331Samw
19115331Samw mutex_exit(&xa->xa_mutex);
19125331Samw }
19135331Samw
19145331Samw int
smb_xa_complete(smb_xa_t * xa)19155331Samw smb_xa_complete(smb_xa_t *xa)
19165331Samw {
19175331Samw int rc;
19185331Samw
19195331Samw mutex_enter(&xa->xa_mutex);
19205331Samw if (xa->xa_flags & (SMB_XA_FLAG_COMPLETE | SMB_XA_FLAG_CLOSE)) {
19215331Samw rc = 0;
19225331Samw } else {
19235331Samw rc = 1;
19245331Samw xa->xa_flags |= SMB_XA_FLAG_COMPLETE;
19255331Samw }
19265331Samw mutex_exit(&xa->xa_mutex);
19275331Samw return (rc);
19285331Samw }
19295331Samw
19305331Samw smb_xa_t *
smb_xa_find(smb_session_t * session,uint16_t pid,uint16_t mid)19315331Samw smb_xa_find(
19325331Samw smb_session_t *session,
19335331Samw uint16_t pid,
19345331Samw uint16_t mid)
19355331Samw {
19365331Samw smb_xa_t *xa;
19375331Samw smb_llist_t *xlist;
19385331Samw
19395331Samw xlist = &session->s_xa_list;
19405331Samw smb_llist_enter(xlist, RW_READER);
19415331Samw xa = smb_llist_head(xlist);
19425331Samw while (xa) {
19435331Samw mutex_enter(&xa->xa_mutex);
19445331Samw if (xa->xa_smb_mid == mid &&
19455331Samw xa->smb_pid == pid &&
19465331Samw !SMB_XA_CLOSED(xa) &&
19475331Samw !(xa->xa_flags & SMB_XA_FLAG_COMPLETE)) {
19485331Samw xa->xa_refcnt++;
19495331Samw ASSERT(xa->xa_refcnt);
19505331Samw mutex_exit(&xa->xa_mutex);
19515331Samw break;
19525331Samw }
19535331Samw mutex_exit(&xa->xa_mutex);
19545331Samw xa = smb_llist_next(xlist, xa);
19555331Samw }
19565331Samw smb_llist_exit(xlist);
19575331Samw return (xa);
19585331Samw }
1959