SmbProcessResult smbcomcreatedirectory(SmbSession *s, SmbHeader *h, uint8_t *, SmbBuffer *b) { int fd; char *path; char *fullpath = nil; SmbTree *t; uint8_t fmt; if (h->wordcount != 0) return SmbProcessResultFormat; if (!smbbuffergetb(b, &fmt) || fmt != 0x04 || !smbbuffergetstring(b, h, SMB_STRING_PATH, &path)) return SmbProcessResultFormat; smblogprint(h->command, "smbcomcreatedirectory: %s\n", path); t = smbidmapfind(s->tidmap, h->tid); if (t == nil) { smbseterror(s, ERRSRV, ERRinvtid); return SmbProcessResultError; } smbstringprint(&fullpath, "%s%s", t->serv->path, path); fd = create(fullpath, OREAD, DMDIR | 0775); if (fd < 0) { smblogprint(h->command, "smbcomcreatedirectory failed: %r\n"); smbseterror(s, ERRDOS, ERRnoaccess); free(path); return SmbProcessResultError; } close(fd); free(fullpath); free(path); return smbbufferputack(s->response, h, &s->peerinfo); }
SmbProcessResult smbcomsetinformation(SmbSession *s, SmbHeader *h, uint8_t *pdata, SmbBuffer *b) { uint16_t attr; uint32_t utime; char *name; if (h->wordcount != 8) return SmbProcessResultFormat; attr = smbnhgets(pdata); pdata += 2; utime = smbnhgetl(pdata); if (!smbbuffergetstring(b, h, SMB_STRING_PATH, &name)) return SmbProcessResultFormat; smblogprint(h->command, "smbcomsetinformation: attr 0x%.4ux utime %lud path %s\n", attr, utime, name); if (utime) { Dir d; memset(&d, 0xff, sizeof(d)); d.name = d.uid = d.gid = d.muid = nil; d.mtime = smbutime2plan9time(utime, s->tzoff); if (dirwstat(name, &d) < 0) { smbseterror(s, ERRDOS, ERRnoaccess); free(name); return SmbProcessResultError; } } free(name); return smbbufferputack(s->response, h, &s->peerinfo); }
SmbProcessResult smbcomflush(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *) { SmbTree *t; SmbFile *f; ushort fid; Dir nulldir; if (h->wordcount != 1) return SmbProcessResultFormat; fid = smbnhgets(pdata); t = smbidmapfind(s->tidmap, h->tid); if (t == nil) { smbseterror(s, ERRSRV, ERRinvtid); return SmbProcessResultError; } f = smbidmapfind(s->fidmap, fid); if (f == nil) { smbseterror(s, ERRDOS, ERRbadfid); return SmbProcessResultError; } memset(&nulldir, 0xff, sizeof(nulldir)); nulldir.name = nulldir.uid = nulldir.gid = nulldir.muid = nil; dirfwstat(f->fd, &nulldir); return smbbufferputack(s->response, h, &s->peerinfo); }
int smbcomtransaction2(SmbSession *s, SmbHeader *h, uint8_t *pdata, SmbBuffer *b) { int rv; char *errmsg; SmbProcessResult pr = SmbProcessResultDie; uint16_t op; errmsg = nil; rv = smbtransactiondecodeprimary2(&s->transaction, h, pdata, b, &errmsg); if (rv < 0) { fmtfail: pr = SmbProcessResultFormat; goto done; } if (rv == 0) { h->wordcount = 0; if (smbbufferputack(s->response, h, &s->peerinfo)) { pr = SmbProcessResultReply; s->nextcommand = SMB_COM_TRANSACTION2_SECONDARY; } goto done; } smblogprint(h->command, "smbcomtransaction2: scount %ud tpcount %lud tdcount %lud maxscount %lud maxpcount %lud maxdcount %lud\n", s->transaction.in.scount, s->transaction.in.tpcount, s->transaction.in.tdcount, s->transaction.in.maxscount, s->transaction.in.maxpcount, s->transaction.in.maxdcount); smbbufferfree(&s->transaction.out.parameters); smbbufferfree(&s->transaction.out.data); s->transaction.out.parameters = smbbuffernew(s->transaction.in.maxpcount); s->transaction.out.data = smbbuffernew(s->transaction.in.maxdcount); if (s->transaction.in.scount != 1) goto fmtfail; op = s->transaction.in.setup[0]; if (op >= smbtrans2optablesize || smbtrans2optable[op].name == nil) { smblogprint(-1, "smbcomtransaction2: function %d unknown\n", op); pr = SmbProcessResultUnimp; goto done; } if (smbtrans2optable[op].process == nil) { smblogprint(-1, "smbcomtransaction2: %s unimplemented\n", smbtrans2optable[op].name); pr = SmbProcessResultUnimp; goto done; } pr = (*smbtrans2optable[op].process)(s, h); if (pr == SmbProcessResultReply) { char *errmsg; errmsg = nil; rv = smbtransactionrespond(&s->transaction, h, &s->peerinfo, s->response, &smbtransactionmethod2, s, &errmsg); if (!rv) { smblogprint(h->command, "smbcomtransaction2: failed: %s\n", errmsg); pr = SmbProcessResultMisc; } else pr = SmbProcessResultOk; } done: free(errmsg); return pr; }
SmbProcessResult smbcomtreedisconnect(SmbSession *s, SmbHeader *h, uchar *, SmbBuffer *) { if (!smbcheckwordcount("comtreedisconnect", h, 0)) return SmbProcessResultFormat; smbtreedisconnectbyid(s, h->tid); return smbbufferputack(s->response, h, &s->peerinfo); }
SmbProcessResult smbcomdelete(SmbSession *s, SmbHeader *h, uint8_t *pdata, SmbBuffer *b) { SmbProcessResult pr; uint16_t sattr; uint8_t fmt; char *pattern = nil; char *dir = nil; char *name = nil; Reprog *r = nil; SmbTree *t; int x, count; SmbDirCache *dc = nil; if (h->wordcount != 1) return SmbProcessResultFormat; sattr = smbnhgets(pdata); if (!smbbuffergetb(b, &fmt) || fmt != 0x04 || !smbbuffergetstring(b, h, SMB_STRING_PATH, &pattern)) return SmbProcessResultFormat; smblogprint(SMB_COM_DELETE, "searchattributes: 0x%.4x\npattern:%s\n", sattr, pattern); smbpathsplit(pattern, &dir, &name); t = smbidmapfind(s->tidmap, h->tid); if (t == nil) { smbseterror(s, ERRSRV, ERRinvtid); pr = SmbProcessResultError; goto done; } dc = smbmkdircache(t, dir); if (dc == nil) { pr = SmbProcessResultMisc; goto done; } r = smbmkrep(name); count = 0; for (x = 0; x < dc->n; x++) { if (!smbmatch(dc->buf[x].name, r)) continue; if (smbremovefile(t, dir, dc->buf[x].name) == 0) count++; } if (count == 0) { smbseterror(s, ERRDOS, ERRnoaccess); pr = SmbProcessResultError; } else pr = smbbufferputack(s->response,h, &s->peerinfo); done: free(pattern); free(dir); free(name); smbdircachefree(&dc); free(r); return pr; }
int smbcomtransaction(SmbSession *s, SmbHeader *h, uint8_t *pdata, SmbBuffer *b) { int rv; char *errmsg; SmbProcessResult pr = SmbProcessResultDie; errmsg = nil; rv = smbtransactiondecodeprimary(&s->transaction, h, pdata, b, &errmsg); if (rv < 0) { pr = SmbProcessResultFormat; goto done; } if (rv == 0) { h->wordcount = 0; if (smbbufferputack(s->response, h, &s->peerinfo)) { pr = SmbProcessResultReply; s->nextcommand = SMB_COM_TRANSACTION_SECONDARY; } goto done; } smblogprint(h->command, "smbcomtransaction: %s scount %ud tpcount %lud tdcount %lud maxscount %lud maxpcount %lud maxdcount %lud\n", s->transaction.in.name, s->transaction.in.scount, s->transaction.in.tpcount, s->transaction.in.tdcount, s->transaction.in.maxscount, s->transaction.in.maxpcount, s->transaction.in.maxdcount); smbbufferfree(&s->transaction.out.parameters); smbbufferfree(&s->transaction.out.data); s->transaction.out.parameters = smbbuffernew(s->transaction.in.maxpcount); s->transaction.out.data = smbbuffernew(s->transaction.in.maxdcount); if (strcmp(s->transaction.in.name, smbglobals.pipelanman) == 0) pr = smbrap2(s); else { smbseterror(s, ERRDOS, ERRbadpath); pr = SmbProcessResultError; goto done; } if (pr == SmbProcessResultReply) { char *errmsg; errmsg = nil; rv = smbtransactionrespond(&s->transaction, h, &s->peerinfo, s->response, &smbtransactionmethod, s, &errmsg); if (!rv) { smblogprint(h->command, "smbcomtransaction: failed: %s\n", errmsg); pr = SmbProcessResultMisc; } else pr = SmbProcessResultOk; } done: free(errmsg); return pr; }
SmbProcessResult smbcomsetinformation2(SmbSession *s, SmbHeader *h, uint8_t *pdata, SmbBuffer *) { uint16_t fid, adate, atime, mdate, mtime; SmbTree *t; SmbFile *f; Dir d; if (h->wordcount != 7) return SmbProcessResultFormat; fid = smbnhgets(pdata); adate = smbnhgets(pdata + 6); atime = smbnhgets(pdata + 8); mdate = smbnhgets(pdata + 10); mtime = smbnhgets(pdata + 12); smblogprint(h->command, "smbcomsetinformation2: fid 0x%.4ux adate 0x%.4ux atime 0x%.4ux mdate 0x%.4ux mtime 0x%.4ux\n", fid, adate, atime, mdate, mtime); t = smbidmapfind(s->tidmap, h->tid); if (t == nil) { smbseterror(s, ERRSRV, ERRinvtid); return SmbProcessResultError; } f = smbidmapfind(s->fidmap, fid); if (f == nil) { smbseterror(s, ERRDOS, ERRbadfid); return SmbProcessResultError; } memset(&d, 0xff, sizeof(d)); d.name = d.uid = d.gid = d.muid = nil; if (adate || atime || mdate || mtime) { //smblogprint(-1, "smbcomsetinformation2: changing times not implemented\n"); // return SmbProcessResultUnimp; /* something to change */ if (!(adate && atime && mdate && mtime)) { /* some null entries */ uint16_t odate, otime; Dir *od = dirfstat(f->fd); if (od == nil) { smbseterror(s, ERRDOS, ERRnoaccess); return SmbProcessResultError; } if (adate || atime) { /* something changed in access time */ if (!(adate && atime)) { /* some nulls in access time */ smbplan9time2datetime(d.atime, s->tzoff, &odate, &otime); if (adate == 0) adate = odate; if (atime == 0) atime = otime; } d.atime = smbdatetime2plan9time(adate, atime, s->tzoff); } if (mdate || mtime) { /* something changed in modify time */ if (!(mdate && mtime)) { /* some nulls in modify time */ smbplan9time2datetime(d.mtime, s->tzoff, &odate, &otime); if (mdate == 0) mdate = odate; if (mtime == 0) mtime = otime; } d.mtime = smbdatetime2plan9time(mdate, mtime, s->tzoff); } free(od); } if (dirfwstat(f->fd, &d) < 0) { smbseterror(s, ERRDOS, ERRnoaccess); return SmbProcessResultError; } } return smbbufferputack(s->response, h, &s->peerinfo); }