/* * Set DOS file attributes. mtime should be NULL for dialects above lm10 */ int smbfs_smb_setpattr(struct smbnode *np, u_int16_t attr, struct timespec *mtime, struct smb_cred *scred) { struct smb_rq *rqp; struct smb_share *ssp = np->n_mount->sm_share; struct mbchain *mbp; u_long time; int error, svtz; rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_SET_INFORMATION, scred); if (error) { free(rqp, M_SMBFSDATA); return error; } svtz = SSTOVC(ssp)->vc_sopt.sv_tz; smb_rq_getrequest(rqp, &mbp); smb_rq_wstart(rqp); mb_put_uint16le(mbp, attr); if (mtime) { smb_time_local2server(mtime, svtz, &time); } else time = 0; mb_put_uint32le(mbp, time); /* mtime */ mb_put_mem(mbp, NULL, 5 * 2, MB_MZERO); smb_rq_wend(rqp); smb_rq_bstart(rqp); mb_put_uint8(mbp, SMB_DT_ASCII); do { error = smbfs_fullpath(mbp, SSTOVC(ssp), np, NULL, 0); if (error) break; mb_put_uint8(mbp, SMB_DT_ASCII); if (SMB_UNICODE_STRINGS(SSTOVC(ssp))) { mb_put_padbyte(mbp); mb_put_uint8(mbp, 0); /* 1st byte of NULL Unicode char */ } mb_put_uint8(mbp, 0); smb_rq_bend(rqp); error = smb_rq_simple(rqp); if (error) { SMBERROR("smb_rq_simple(rqp) => error %d\n", error); break; } } while(0); smb_rq_done(rqp); free(rqp, M_SMBFSDATA); return error; }
int smb_put_dmem(struct mbchain *mbp, struct smb_vc *vcp, const char *src, size_t size, int caseopt) { struct iconv_drv *dp = vcp->vc_toserver; if (size == 0) return 0; if (dp == NULL) { return mb_put_mem(mbp, src, size, MB_MSYSTEM); } mbp->mb_copy = smb_copy_iconv; mbp->mb_udata = dp; if (SMB_UNICODE_STRINGS(vcp)) mb_put_padbyte(mbp); return mb_put_mem(mbp, src, size, MB_MCUSTOM); }
int smbfs_fullpath(struct mbchain *mbp, struct smb_vc *vcp, struct smbnode *dnp, const char *name, int nmlen) { int caseopt = SMB_CS_NONE; int error; if (SMB_UNICODE_STRINGS(vcp)) { error = mb_put_padbyte(mbp); if (error) return error; } if (SMB_DIALECT(vcp) < SMB_DIALECT_LANMAN1_0) caseopt |= SMB_CS_UPPER; if (dnp != NULL) { error = smb_put_dmem(mbp, vcp, dnp->n_rpath, dnp->n_rplen, caseopt); if (error) return error; if (name) { /* Put the separator */ if (SMB_UNICODE_STRINGS(vcp)) error = mb_put_uint16le(mbp, '\\'); else error = mb_put_uint8(mbp, '\\'); if (error) return error; /* Put the name */ error = smb_put_dmem(mbp, vcp, name, nmlen, caseopt); if (error) return error; } } /* Put NULL terminator. */ if (SMB_UNICODE_STRINGS(vcp)) error = mb_put_uint16le(mbp, 0); else error = mb_put_uint8(mbp, 0); return error; }
static int smbfs_smb_search(struct smbfs_fctx *ctx) { struct smb_vc *vcp = SSTOVC(ctx->f_ssp); struct smb_rq *rqp; struct mbchain *mbp; struct mdchain *mdp; u_int8_t wc, bt; u_int16_t ec, dlen, bc; int maxent, error, iseof = 0; maxent = min(ctx->f_left, (vcp->vc_txmax - SMB_HDRLEN - 3) / SMB_DENTRYLEN); if (ctx->f_rq) { smb_rq_done(ctx->f_rq); ctx->f_rq = NULL; } error = smb_rq_alloc(SSTOCP(ctx->f_ssp), SMB_COM_SEARCH, ctx->f_scred, &rqp); if (error) return error; ctx->f_rq = rqp; smb_rq_getrequest(rqp, &mbp); smb_rq_wstart(rqp); mb_put_uint16le(mbp, maxent); /* max entries to return */ mb_put_uint16le(mbp, ctx->f_attrmask); smb_rq_wend(rqp); smb_rq_bstart(rqp); mb_put_uint8(mbp, SMB_DT_ASCII); /* buffer format */ if (ctx->f_flags & SMBFS_RDD_FINDFIRST) { error = smbfs_fullpath(mbp, vcp, ctx->f_dnp, ctx->f_wildcard, ctx->f_wclen); if (error) return error; mb_put_uint8(mbp, SMB_DT_VARIABLE); mb_put_uint16le(mbp, 0); /* context length */ ctx->f_flags &= ~SMBFS_RDD_FINDFIRST; } else { if (SMB_UNICODE_STRINGS(vcp)) { mb_put_padbyte(mbp); mb_put_uint8(mbp, 0); } mb_put_uint8(mbp, 0); /* file name length */ mb_put_uint8(mbp, SMB_DT_VARIABLE); mb_put_uint16le(mbp, SMB_SKEYLEN); mb_put_mem(mbp, ctx->f_skey, SMB_SKEYLEN, MB_MSYSTEM); } smb_rq_bend(rqp); error = smb_rq_simple(rqp); if (error) { if (rqp->sr_errclass == ERRDOS && rqp->sr_serror == ERRnofiles) { error = 0; iseof = 1; ctx->f_flags |= SMBFS_RDD_EOF; } else return error; } smb_rq_getreply(rqp, &mdp); md_get_uint8(mdp, &wc); if (wc != 1) return iseof ? ENOENT : EBADRPC; md_get_uint16le(mdp, &ec); if (ec == 0) return ENOENT; ctx->f_ecnt = ec; md_get_uint16le(mdp, &bc); if (bc < 3) return EBADRPC; bc -= 3; md_get_uint8(mdp, &bt); if (bt != SMB_DT_VARIABLE) return EBADRPC; md_get_uint16le(mdp, &dlen); if (dlen != bc || dlen % SMB_DENTRYLEN != 0) return EBADRPC; return 0; }