diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/lib/libsmbfs/netsmb/smb_lib.h | 1 | ||||
-rw-r--r-- | usr/src/lib/libsmbfs/smb/ctx.c | 26 | ||||
-rw-r--r-- | usr/src/uts/common/fs/smbclnt/netsmb/smb_conn.c | 29 | ||||
-rw-r--r-- | usr/src/uts/common/fs/smbclnt/netsmb/smb_conn.h | 4 | ||||
-rw-r--r-- | usr/src/uts/common/fs/smbclnt/netsmb/smb_dev.c | 31 | ||||
-rw-r--r-- | usr/src/uts/common/fs/smbclnt/netsmb/smb_usr.c | 24 | ||||
-rw-r--r-- | usr/src/uts/common/netsmb/smb_dev.h | 7 |
7 files changed, 119 insertions, 3 deletions
diff --git a/usr/src/lib/libsmbfs/netsmb/smb_lib.h b/usr/src/lib/libsmbfs/netsmb/smb_lib.h index 90bfda6313..7756ce2638 100644 --- a/usr/src/lib/libsmbfs/netsmb/smb_lib.h +++ b/usr/src/lib/libsmbfs/netsmb/smb_lib.h @@ -256,6 +256,7 @@ int smb_ctx_setworkgroup(struct smb_ctx *, const char *, int); int smb_ctx_setpassword(struct smb_ctx *, const char *, int); int smb_ctx_setsrvaddr(struct smb_ctx *, const char *); int smb_ctx_opt(struct smb_ctx *, int, const char *); +int smb_ctx_findvc(struct smb_ctx *, int, int); int smb_ctx_negotiate(struct smb_ctx *, int, int, char *); int smb_ctx_tdis(struct smb_ctx *ctx); int smb_ctx_lookup(struct smb_ctx *, int, int); diff --git a/usr/src/lib/libsmbfs/smb/ctx.c b/usr/src/lib/libsmbfs/smb/ctx.c index 51896bf128..ae79686869 100644 --- a/usr/src/lib/libsmbfs/smb/ctx.c +++ b/usr/src/lib/libsmbfs/smb/ctx.c @@ -1049,6 +1049,14 @@ smb_ctx_resolve(struct smb_ctx *ctx) bcopy(salocal, &ssn->ioc_local.nb, sizeof (struct sockaddr_nb)); + error = smb_ctx_findvc(ctx, SMBL_VC, 0); + if (error == 0) { + /* re-use and existing VC */ + ctx->ct_flags |= SMBCF_RESOLVED | SMBCF_SSNACTIVE; + return (0); + } + + /* Make a new connection via smb_ctx_negotiate()... */ error = smb_ctx_negotiate(ctx, SMBL_SHARE, SMBLK_CREATE, ssn->ioc_workgroup); if (error) @@ -1251,6 +1259,24 @@ out: return (rc); } +int +smb_ctx_findvc(struct smb_ctx *ctx, int level, int flags) +{ + struct smbioc_lookup rq; + int error = 0; + + if ((error = smb_ctx_gethandle(ctx))) + return (error); + + bzero(&rq, sizeof (rq)); + bcopy(&ctx->ct_ssn, &rq.ioc_ssn, sizeof (struct smbioc_ossn)); + bcopy(&ctx->ct_sh, &rq.ioc_sh, sizeof (struct smbioc_oshare)); + + rq.ioc_flags = flags; + rq.ioc_level = level; + + return (smb_ctx_ioctl(ctx, SMBIOC_FINDVC, &rq)); +} /* * adds a GSSAPI wrapper diff --git a/usr/src/uts/common/fs/smbclnt/netsmb/smb_conn.c b/usr/src/uts/common/fs/smbclnt/netsmb/smb_conn.c index b0b50b80e1..7c902eeff0 100644 --- a/usr/src/uts/common/fs/smbclnt/netsmb/smb_conn.c +++ b/usr/src/uts/common/fs/smbclnt/netsmb/smb_conn.c @@ -198,6 +198,35 @@ smb_sm_lookupvc( return (ENOENT); } +int +smb_sm_findvc( + struct smb_vcspec *vcspec, + struct smb_cred *scred, + struct smb_vc **vcpp) +{ + struct smb_vc *vcp; + int error; + + *vcpp = vcp = NULL; + + SMB_CO_LOCK(&smb_vclist); + error = smb_sm_lookupvc(vcspec, scred, &vcp); + SMB_CO_UNLOCK(&smb_vclist); + + /* Return if smb_sm_lookupvc fails */ + if (error != 0) + return (error); + + /* Ingore any VC that's not active. */ + if (vcp->vc_state != SMBIOD_ST_VCACTIVE) { + smb_vc_rele(vcp); + return (ENOENT); + } + + /* Active VC. Return it held. */ + *vcpp = vcp; + return (error); +} int smb_sm_negotiate( diff --git a/usr/src/uts/common/fs/smbclnt/netsmb/smb_conn.h b/usr/src/uts/common/fs/smbclnt/netsmb/smb_conn.h index 8211c01d1b..e2a55b970d 100644 --- a/usr/src/uts/common/fs/smbclnt/netsmb/smb_conn.h +++ b/usr/src/uts/common/fs/smbclnt/netsmb/smb_conn.h @@ -33,7 +33,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -421,6 +421,8 @@ int smb_sm_init(void); int smb_sm_idle(void); void smb_sm_done(void); +int smb_sm_findvc(struct smb_vcspec *vcspec, + struct smb_cred *scred, struct smb_vc **vcpp); int smb_sm_negotiate(struct smb_vcspec *vcspec, struct smb_cred *scred, struct smb_vc **vcpp); int smb_sm_ssnsetup(struct smb_vcspec *vcspec, diff --git a/usr/src/uts/common/fs/smbclnt/netsmb/smb_dev.c b/usr/src/uts/common/fs/smbclnt/netsmb/smb_dev.c index 6e40480724..a2fc78bd4c 100644 --- a/usr/src/uts/common/fs/smbclnt/netsmb/smb_dev.c +++ b/usr/src/uts/common/fs/smbclnt/netsmb/smb_dev.c @@ -447,6 +447,36 @@ nsmb_ioctl(dev_t dev, SMBIOC_RW_COPYOUT_SIZE, mode); break; + case SMBIOC_FINDVC: + /* Should be no VC and no share */ + if (sdp->sd_vc || sdp->sd_share) { + error = EISCONN; + break; + } + sioc = kmem_alloc(sizeof (*sioc), KM_SLEEP); + if (ddi_copyin((void *)arg, sioc, + sizeof (*sioc), mode)) { + error = EFAULT; + break; + } + vcp = NULL; + ssp = NULL; + error = smb_usr_findvc(sioc, &scred, &vcp); + if (error) + break; + if (vcp) { + /* + * The VC has a hold from _findvc + * which we keep until nsmb_close(). + */ + sdp->sd_level = SMBL_VC; + sdp->sd_vc = vcp; + } + (void) ddi_copyout(sioc, (void *)arg, + SMBIOC_LOOK_COPYOUT_SIZE, mode); + + break; + case SMBIOC_NEGOTIATE: /* Should be no VC (and no share) */ if (sdp->sd_vc || sdp->sd_share) { @@ -735,6 +765,7 @@ nsmb_ioctl(dev_t dev, if (rwrq) kmem_free(rwrq, sizeof (*rwrq)); + /* SMBIOC_FINDVC */ /* SMBIOC_NEGOTIATE */ /* SMBIOC_SSNSETUP */ /* SMBIOC_TCON */ diff --git a/usr/src/uts/common/fs/smbclnt/netsmb/smb_usr.c b/usr/src/uts/common/fs/smbclnt/netsmb/smb_usr.c index e8af12ba20..886c7aadd1 100644 --- a/usr/src/uts/common/fs/smbclnt/netsmb/smb_usr.c +++ b/usr/src/uts/common/fs/smbclnt/netsmb/smb_usr.c @@ -183,6 +183,30 @@ smb_usr_ioc2sharespec(struct smbioc_oshare *dp, struct smb_sharespec *spec) } int +smb_usr_findvc(struct smbioc_lookup *dp, struct smb_cred *scred, + struct smb_vc **vcpp) +{ + struct smb_vc *vcp = NULL; + struct smb_vcspec *vspec = NULL; + int error = 0; + + if (dp->ioc_flags & SMBLK_CREATE) + return (EINVAL); + if (dp->ioc_level != SMBL_VC) + return (EINVAL); + vspec = kmem_zalloc(sizeof (struct smb_vcspec), KM_SLEEP); + error = smb_usr_ioc2vcspec(&dp->ioc_ssn, vspec); + if (error) + goto out; + error = smb_sm_findvc(vspec, scred, &vcp); + if (error == 0) + *vcpp = vcp; +out: + smb_usr_vcspec_free(vspec); + return (error); +} + +int smb_usr_negotiate(struct smbioc_lookup *dp, struct smb_cred *scred, struct smb_vc **vcpp) { diff --git a/usr/src/uts/common/netsmb/smb_dev.h b/usr/src/uts/common/netsmb/smb_dev.h index b414bcf9b8..8bcbb5de98 100644 --- a/usr/src/uts/common/netsmb/smb_dev.h +++ b/usr/src/uts/common/netsmb/smb_dev.h @@ -77,9 +77,9 @@ * make them incompatible with an old driver. */ #define NSMB_VERMAJ 1 -#define NSMB_VERMIN 3500 +#define NSMB_VERMIN 3600 #define NSMB_VERSION (NSMB_VERMAJ * 100000 + NSMB_VERMIN) -#define NSMB_VER_STR "1.35" +#define NSMB_VER_STR "1.36" #define NSMBFL_OPEN 0x0001 #define NSMBFL_NEWVC 0x0002 @@ -358,6 +358,7 @@ typedef enum nsmb_ioc { SMBIOC_LOOKUP, SMBIOC_READ, SMBIOC_WRITE, + SMBIOC_FINDVC, SMBIOC_NEGOTIATE, SMBIOC_SSNSETUP, SMBIOC_TCON, @@ -402,6 +403,8 @@ typedef struct smb_dev { /* * Compound user interface */ +int smb_usr_findvc(struct smbioc_lookup *dp, struct smb_cred *scred, + struct smb_vc **vcpp); int smb_usr_negotiate(struct smbioc_lookup *dp, struct smb_cred *scred, struct smb_vc **vcpp); int smb_usr_ssnsetup(struct smbioc_lookup *dp, struct smb_cred *scred, |