/* * Here we expect something like "[proto:]//[user@]host[:psmb[:pnb]][/share][/path]" */ int smb_ctx_parseunc(struct smb_ctx *ctx, const char *unc, int sharetype, const char **next) { const char *p = unc; char *p1, *psmb, *pnb; char tmp[1024]; int error ; ctx->ct_parsedlevel = SMBL_NONE; if (*p++ != '/' || *p++ != '/') { smb_error("UNC should start with '//'", 0); return EINVAL; } p1 = tmp; error = getsubstring(p, '@', p1, sizeof(tmp), &p); if (!error) { if (ctx->ct_maxlevel < SMBL_VC) { smb_error("no user name required", 0); return EINVAL; } if (*p1 == 0) { smb_error("empty user name", 0); return EINVAL; } error = smb_ctx_setuser(ctx, tmp); if (error) return error; ctx->ct_parsedlevel = SMBL_VC; } error = getsubstring(p, '/', p1, sizeof(tmp), &p); if (error) { error = getsubstring(p, '\0', p1, sizeof(tmp), &p); if (error) { smb_error("no server name found", 0); return error; } } if (*p1 == 0) { smb_error("empty server name", 0); return EINVAL; } /* * Check for port number specification. */ psmb = strchr(tmp, ':'); if (psmb) { *psmb++ = '\0'; pnb = strchr(psmb, ':'); if (pnb) { *pnb++ = '\0'; error = smb_ctx_setnbport(ctx, atoi(pnb)); if (error) { smb_error("Invalid NetBIOS port number", 0); return error; } } error = smb_ctx_setsmbport(ctx, atoi(psmb)); if (error) { smb_error("Invalid SMB port number", 0); return error; } } error = smb_ctx_setserver(ctx, tmp); if (error) return error; if (sharetype == SMB_ST_NONE) { *next = p; return 0; } if (*p != 0 && ctx->ct_maxlevel < SMBL_SHARE) { smb_error("no share name required", 0); return EINVAL; } error = getsubstring(p, '/', p1, sizeof(tmp), &p); if (error) { error = getsubstring(p, '\0', p1, sizeof(tmp), &p); if (error) { smb_error("unexpected end of line", 0); return error; } } if (*p1 == 0 && ctx->ct_minlevel >= SMBL_SHARE) { smb_error("empty share name", 0); return EINVAL; } *next = p; if (*p1 == 0) return 0; error = smb_ctx_setshare(ctx, p1, sharetype); return error; }
/* * Here we expect something like "[proto:]//[user@]host[/share][/path]" */ int smb_ctx_parseunc(struct smb_ctx *ctx, const char *unc, int sharetype, const char **next) { const char *p = unc; char *p1; char tmp[1024]; int error ; ctx->ct_parsedlevel = SMBL_NONE; if (*p++ != '/' || *p++ != '/') { smb_error("UNC should start with '//'", 0); return EINVAL; } p1 = tmp; error = getsubstring(p, '@', p1, sizeof(tmp), &p); if (!error) { if (ctx->ct_maxlevel < SMBL_VC) { smb_error("no user name required", 0); return EINVAL; } if (*p1 == 0) { smb_error("empty user name", 0); return EINVAL; } error = smb_ctx_setuser(ctx, tmp); if (error) return error; ctx->ct_parsedlevel = SMBL_VC; } error = getsubstring(p, '/', p1, sizeof(tmp), &p); if (error) { error = getsubstring(p, '\0', p1, sizeof(tmp), &p); if (error) { smb_error("no server name found", 0); return error; } } if (*p1 == 0) { smb_error("empty server name", 0); return EINVAL; } error = smb_ctx_setserver(ctx, tmp); if (error) return error; if (sharetype == SMB_ST_NONE) { *next = p; return 0; } if (*p != 0 && ctx->ct_maxlevel < SMBL_SHARE) { smb_error("no share name required", 0); return EINVAL; } error = getsubstring(p, '/', p1, sizeof(tmp), &p); if (error) { error = getsubstring(p, '\0', p1, sizeof(tmp), &p); if (error) { smb_error("unexpected end of line", 0); return error; } } if (*p1 == 0 && ctx->ct_minlevel >= SMBL_SHARE) { smb_error("empty share name", 0); return EINVAL; } *next = p; if (*p1 == 0) return 0; error = smb_ctx_setshare(ctx, p1, sharetype); return error; }
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; }