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; }
void smbsearchfree(SmbSearch **searchp) { SmbSearch *search = *searchp; if (search) { smbdircachefree(&search->dc); free(search->rep); free(search); *searchp = nil; } }
SmbProcessResult smbtrans2findfirst2(SmbSession *s, SmbHeader *h) { SmbBuffer *b; char *pattern = nil; char *dir = nil; char *name = nil; ushort searchattributes, searchcount, flags, informationlevel; ulong searchstoragetype; SmbDirCache *dc = nil; ushort e; ulong nameoffset; ushort eos; SmbSearch *search; SmbProcessResult pr; Reprog *r = nil; SmbTree *t; int debug; debug = smboptable[h->command].debug || smbtrans2optable[SMB_TRANS2_FIND_FIRST2].debug || smbglobals.log.find; poolcheck(mainmem); b = smbbufferinit(s->transaction.in.parameters, s->transaction.in.parameters, s->transaction.in.tpcount); if (!smbbuffergets(b, &searchattributes) || !smbbuffergets(b, &searchcount) || !smbbuffergets(b, &flags) || !smbbuffergets(b, &informationlevel) || !smbbuffergetl(b, &searchstoragetype) || !smbbuffergetstring(b, h, SMB_STRING_PATH, &pattern)) { pr = SmbProcessResultFormat; goto done; } smbloglock(); smblogprintif(debug, "searchattributes: 0x%.4ux\n", searchattributes); smblogprintif(debug, "searchcount: 0x%.4ux\n", searchcount); smblogprintif(debug, "flags: 0x%.4ux\n", flags); smblogprintif(debug, "informationlevel: 0x%.4ux\n", informationlevel); smblogprintif(debug, "searchstoragetype: 0x%.8lux\n", searchstoragetype); smblogprintif(debug, "pattern: %s\n", pattern); smblogunlock(); smbpathsplit(pattern, &dir, &name); if (informationlevel != SMB_INFO_STANDARD && informationlevel != SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { smblogprint(-1, "smbtrans2findfirst2: infolevel 0x%.4ux not implemented\n", informationlevel); smbseterror(s, ERRDOS, ERRunknownlevel); pr = SmbProcessResultError; goto done; } t = smbidmapfind(s->tidmap, h->tid); if (t == nil) { smbseterror(s, ERRSRV, ERRinvtid); pr = SmbProcessResultError; goto done; } dc = smbmkdircache(t, dir); if (dc == nil) { smbseterror(s, ERRDOS, ERRnoaccess); pr = SmbProcessResultError; goto done; } poolcheck(mainmem); r = smbmkrep(name); populate(s, dc, r, informationlevel, flags, searchcount, &e, &nameoffset); poolcheck(mainmem); eos = dc->i >= dc->n; if ((flags & SMB_FIND_CLOSE) != 0 || ((flags & SMB_FIND_CLOSE_EOS) != 0 && eos)) smbdircachefree(&dc); poolcheck(mainmem); if (dc) { /* create a search handle */ search = smbsearchnew(s, dc, r, t); r = nil; dc = nil; } else search = nil; smbbufferputs(s->transaction.out.parameters, search ? search->id : 0); smbbufferputs(s->transaction.out.parameters, e); smbbufferputs(s->transaction.out.parameters, eos); smbbufferputs(s->transaction.out.parameters, 0); smbbufferputs(s->transaction.out.parameters, nameoffset); pr = SmbProcessResultReply; done: smbbufferfree(&b); free(pattern); free(dir); free(name); smbdircachefree(&dc); free(r); return pr; }