int smb_ctx_login(struct smb_ctx *ctx) { struct smbioc_ossn *ssn = &ctx->ct_ssn; struct smbioc_oshare *sh = &ctx->ct_sh; int error; if ((ctx->ct_flags & SMBCF_RESOLVED) == 0) { smb_error("smb_ctx_resolve() should be called first", 0); return EINVAL; } if (ctx->ct_fd != -1) { close(ctx->ct_fd); ctx->ct_fd = -1; } error = smb_ctx_gethandle(ctx); if (error) { smb_error("can't get handle to requester", 0); return EINVAL; } if (ioctl(ctx->ct_fd, SMBIOC_OPENSESSION, ssn) == -1) { error = errno; smb_error("can't open session to server %s", error, ssn->ioc_srvname); return error; } if (sh->ioc_share[0] == 0) return 0; if (ioctl(ctx->ct_fd, SMBIOC_OPENSHARE, sh) == -1) { error = errno; smb_error("can't connect to share //%s/%s", error, ssn->ioc_srvname, sh->ioc_share); return error; } return 0; }
int smb_ctx_lookup(struct smb_ctx *ctx, int level, int flags) { struct smbioc_lookup rq; int error; if ((ctx->ct_flags & SMBCF_RESOLVED) == 0) { smb_error("smb_ctx_lookup() data is not resolved", 0); return EINVAL; } if (ctx->ct_fd != -1) { close(ctx->ct_fd); ctx->ct_fd = -1; } error = smb_ctx_gethandle(ctx); if (error) { smb_error("can't get handle to requester (no /dev/"NSMB_NAME"* device)", 0); return EINVAL; } 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; if (ioctl(ctx->ct_fd, SMBIOC_LOOKUP, &rq) == -1) { error = errno; if (flags & SMBLK_CREATE) smb_error("unable to open connection", error); return error; } return 0; }
/* * Try making a connection with the server described by * the info in the smb_iod_ssn_t arg. If successful, * start an IOD thread to service it, then return to * the client side of the door. */ int iod_newvc(smb_iod_ssn_t *clnt_ssn) { smb_ctx_t *ctx; thread_t tid; int err; /* * This needs to essentially "clone" the smb_ctx_t * from the client side of the door, or at least * as much of it as we need while creating a VC. */ err = smb_ctx_alloc(&ctx); if (err) return (err); bcopy(clnt_ssn, &ctx->ct_iod_ssn, sizeof (ctx->ct_iod_ssn)); /* * Do the initial connection setup here, so we can * report the outcome to the door client. */ err = smb_iod_connect(ctx); if (err != 0) goto out; /* * Create the driver session now, so we don't * race with the door client findvc call. */ if ((err = smb_ctx_gethandle(ctx)) != 0) goto out; if (ioctl(ctx->ct_dev_fd, SMBIOC_SSN_CREATE, &ctx->ct_ssn) < 0) { err = errno; goto out; } /* The rest happens in the iod_work thread. */ err = thr_create(NULL, 0, iod_work, ctx, THR_DETACHED, &tid); if (err == 0) { /* * Given to the new thread. * free at end of iod_work */ ctx = NULL; } out: if (ctx) smb_ctx_free(ctx); return (err); }
int smb_ctx_lookup(struct smb_ctx *ctx, int level, int flags) { struct smbioc_lookup rq; int error; if ((ctx->ct_flags & SMBCF_RESOLVED) == 0) { smb_error("smb_ctx_lookup() data is not resolved", 0); return EINVAL; } if (ctx->ct_fd != -1) { smb_kops.ko_close(ctx->ct_fd); ctx->ct_fd = -1; } error = smb_ctx_gethandle(ctx); if (error) { smb_error("can't get handle to requester (no /dev/"NSMB_NAME"* device available)", 0); return EINVAL; } 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; if (smb_kops.ko_ioctl(ctx->ct_fd, SMBIOC_LOOKUP, &rq) == -1) { error = errno; smb_kops.ko_close(ctx->ct_fd); ctx->ct_fd = -1; /* * Fallback to *SMBSERVER as NetBIOS name. At least * Windows NT and Windows XP require this (or valid * NetBIOS server name), otherwise they refuse connection. */ if (smb_ctx_setserver(ctx, "*SMBSERVER") != 0) goto fail; error = smb_ctx_resolve(ctx); if (error) goto fail; error = smb_ctx_gethandle(ctx); if (error) goto fail; bcopy(&ctx->ct_ssn, &rq.ioc_ssn, sizeof(struct smbioc_ossn)); if (smb_kops.ko_ioctl(ctx->ct_fd, SMBIOC_LOOKUP, &rq) != -1) goto success; error = errno; fail: if (flags & SMBLK_CREATE) smb_error("unable to open connection", error); return error; } success: return 0; }