18ccd4a63SDavid du Colombier #include "headers.h"
28ccd4a63SDavid du Colombier
38ccd4a63SDavid du Colombier static void
smblogprintattr(int cmd,ushort attr)48ccd4a63SDavid du Colombier smblogprintattr(int cmd, ushort attr)
58ccd4a63SDavid du Colombier {
68ccd4a63SDavid du Colombier if (attr & SMB_ATTR_READ_ONLY)
78ccd4a63SDavid du Colombier smblogprint(cmd, " readonly");
88ccd4a63SDavid du Colombier if (attr & SMB_ATTR_HIDDEN)
98ccd4a63SDavid du Colombier smblogprint(cmd, " hidden");
108ccd4a63SDavid du Colombier if (attr & SMB_ATTR_SYSTEM)
118ccd4a63SDavid du Colombier smblogprint(cmd, " system");
128ccd4a63SDavid du Colombier if (attr & SMB_ATTR_DIRECTORY)
138ccd4a63SDavid du Colombier smblogprint(cmd, " directory");
148ccd4a63SDavid du Colombier if (attr & SMB_ATTR_ARCHIVE)
158ccd4a63SDavid du Colombier smblogprint(cmd, " archive");
168ccd4a63SDavid du Colombier }
178ccd4a63SDavid du Colombier
188ccd4a63SDavid du Colombier static SmbFile *
openfile(SmbSession * s,SmbTree * t,char * path,ushort mode,ushort attr,ushort ofun,ulong createoptions,uvlong createsize,ushort * fidp,Dir ** dp,ushort * actionp)198ccd4a63SDavid du Colombier openfile(SmbSession *s, SmbTree *t, char *path, ushort mode, ushort attr, ushort ofun, ulong createoptions, uvlong createsize,
208ccd4a63SDavid du Colombier ushort *fidp, Dir **dp, ushort *actionp)
218ccd4a63SDavid du Colombier {
228ccd4a63SDavid du Colombier int p9mode;
238ccd4a63SDavid du Colombier int share;
248ccd4a63SDavid du Colombier Dir *d = nil;
258ccd4a63SDavid du Colombier int fd = -1;
268ccd4a63SDavid du Colombier ushort action;
278ccd4a63SDavid du Colombier SmbFile *f = nil;
288ccd4a63SDavid du Colombier SmbSharedFile *sf = nil;
298ccd4a63SDavid du Colombier char *fullpath = nil;
308ccd4a63SDavid du Colombier int diropen = 0;
318ccd4a63SDavid du Colombier
3286a363ceSDavid du Colombier //smblogprint(-1, "%s A %r", path);
338ccd4a63SDavid du Colombier p9mode = (mode >> SMB_OPEN_MODE_ACCESS_SHIFT) & SMB_OPEN_MODE_ACCESS_MASK;
348ccd4a63SDavid du Colombier share = (mode >> SMB_OPEN_MODE_SHARE_SHIFT) & SMB_OPEN_MODE_SHARE_MASK;
358ccd4a63SDavid du Colombier if (share == SMB_OPEN_MODE_SHARE_COMPATIBILITY) {
368ccd4a63SDavid du Colombier badshare:
3786a363ceSDavid du Colombier //smblogprint(-1, "%s SMB_OPEN_MODE_SHARE_COMPATIBILITY", path);
388ccd4a63SDavid du Colombier smbseterror(s, ERRDOS, ERRbadshare);
398ccd4a63SDavid du Colombier goto done;
408ccd4a63SDavid du Colombier }
418ccd4a63SDavid du Colombier smbstringprint(&fullpath, "%s%s", t->serv->path, path);
428ccd4a63SDavid du Colombier d = dirstat(fullpath);
438ccd4a63SDavid du Colombier if (d) {
448ccd4a63SDavid du Colombier /* file exists */
458ccd4a63SDavid du Colombier int ofunexist;
468ccd4a63SDavid du Colombier if (d->mode & DMDIR) {
478ccd4a63SDavid du Colombier if (createoptions & SMB_CO_FILE) {
488ccd4a63SDavid du Colombier smbseterror(s, ERRDOS, ERRnoaccess);
498ccd4a63SDavid du Colombier goto done;
508ccd4a63SDavid du Colombier }
518ccd4a63SDavid du Colombier }
528ccd4a63SDavid du Colombier else if (createoptions & SMB_CO_DIRECTORY) {
538ccd4a63SDavid du Colombier smbseterror(s, ERRDOS, ERRnoaccess);
548ccd4a63SDavid du Colombier goto done;
558ccd4a63SDavid du Colombier }
568ccd4a63SDavid du Colombier
578ccd4a63SDavid du Colombier sf = smbsharedfileget(d, p9mode, &share);
588ccd4a63SDavid du Colombier if (sf == nil)
598ccd4a63SDavid du Colombier goto badshare;
608ccd4a63SDavid du Colombier action = 1;
618ccd4a63SDavid du Colombier ofunexist = (ofun >> SMB_OFUN_EXIST_SHIFT) & SMB_OFUN_EXIST_MASK;
628ccd4a63SDavid du Colombier if (ofunexist == SMB_OFUN_EXIST_FAIL) {
638ccd4a63SDavid du Colombier smbseterror(s, ERRDOS, ERRfilexists);
648ccd4a63SDavid du Colombier goto done;
658ccd4a63SDavid du Colombier }
668ccd4a63SDavid du Colombier else if (ofunexist == SMB_OFUN_EXIST_TRUNCATE) {
678ccd4a63SDavid du Colombier if ((d->mode & DMDIR) || (p9mode != OWRITE && p9mode != ORDWR)) {
688ccd4a63SDavid du Colombier smbseterror(s, ERRDOS, ERRbadaccess);
698ccd4a63SDavid du Colombier goto done;
708ccd4a63SDavid du Colombier }
718ccd4a63SDavid du Colombier p9mode |= OTRUNC;
728ccd4a63SDavid du Colombier action = 3;
738ccd4a63SDavid du Colombier }
748ccd4a63SDavid du Colombier else if (ofunexist != SMB_OFUN_EXIST_OPEN) {
758ccd4a63SDavid du Colombier smbseterror(s, ERRDOS, ERRbadaccess);
768ccd4a63SDavid du Colombier goto done;
778ccd4a63SDavid du Colombier }
788ccd4a63SDavid du Colombier if (d->mode & DMDIR)
798ccd4a63SDavid du Colombier diropen = 1;
808ccd4a63SDavid du Colombier else
818ccd4a63SDavid du Colombier fd = open(fullpath, p9mode);
828ccd4a63SDavid du Colombier }
838ccd4a63SDavid du Colombier else {
848ccd4a63SDavid du Colombier /* file does not exist */
858ccd4a63SDavid du Colombier ulong p9attr;
868ccd4a63SDavid du Colombier action = 3;
878ccd4a63SDavid du Colombier if ((ofun & SMB_OFUN_NOEXIST_CREATE) == 0) {
888ccd4a63SDavid du Colombier smbseterror(s, ERRDOS, ERRbadfile);
898ccd4a63SDavid du Colombier goto done;
908ccd4a63SDavid du Colombier }
918ccd4a63SDavid du Colombier if (createsize != 0) {
928ccd4a63SDavid du Colombier smbseterror(s, ERRDOS, ERRunsup);
938ccd4a63SDavid du Colombier goto done;
948ccd4a63SDavid du Colombier }
958ccd4a63SDavid du Colombier //smblogprint(-1, "creating: attr 0x%.4ux co 0x%.8lux\n", attr, createoptions);
968ccd4a63SDavid du Colombier if (createoptions & SMB_CO_FILE) {
978ccd4a63SDavid du Colombier attr &= SMB_ATTR_DIRECTORY;
988ccd4a63SDavid du Colombier if (attr == 0)
998ccd4a63SDavid du Colombier attr = SMB_ATTR_NORMAL;
1008ccd4a63SDavid du Colombier }
1018ccd4a63SDavid du Colombier else if (createoptions & SMB_CO_DIRECTORY) {
1028ccd4a63SDavid du Colombier attr &= ~SMB_ATTR_NORMAL;
1038ccd4a63SDavid du Colombier attr |= SMB_ATTR_DIRECTORY;
104*3e5d0078SDavid du Colombier p9mode = OREAD;
1058ccd4a63SDavid du Colombier }
1068ccd4a63SDavid du Colombier //smblogprint(-1, "creating: before conversion attr 0x%.4ux\n", attr);
1078ccd4a63SDavid du Colombier p9attr = smbdosattr2plan9mode(attr);
1088ccd4a63SDavid du Colombier //smblogprint(-1, "creating: after conversion p9attr 0%.uo\n", p9attr);
1098ccd4a63SDavid du Colombier fd = create(fullpath, p9mode, p9attr);
1108ccd4a63SDavid du Colombier if (fd >= 0) {
1118ccd4a63SDavid du Colombier d = dirfstat(fd);
1128ccd4a63SDavid du Colombier sf = smbsharedfileget(d, p9mode, &share);
1138ccd4a63SDavid du Colombier if (sf == nil) {
1148ccd4a63SDavid du Colombier close(fd);
1158ccd4a63SDavid du Colombier remove(path);
1168ccd4a63SDavid du Colombier goto badshare;
1178ccd4a63SDavid du Colombier }
1188ccd4a63SDavid du Colombier }
1198ccd4a63SDavid du Colombier }
12086a363ceSDavid du Colombier //smblogprint(-1, "%s D %r", fullpath);
1218ccd4a63SDavid du Colombier if (!diropen && fd < 0) {
1228ccd4a63SDavid du Colombier smbseterror(s, ERRSRV, ERRaccess);
1238ccd4a63SDavid du Colombier goto done;
1248ccd4a63SDavid du Colombier }
1258ccd4a63SDavid du Colombier f = smbemalloc(sizeof(SmbFile));
1268ccd4a63SDavid du Colombier if (diropen) {
1278ccd4a63SDavid du Colombier f->ioallowed = 0;
1288ccd4a63SDavid du Colombier f->fd = -1;
1298ccd4a63SDavid du Colombier }
1308ccd4a63SDavid du Colombier else {
1318ccd4a63SDavid du Colombier f->ioallowed = 1;
1328ccd4a63SDavid du Colombier f->fd = fd;
1338ccd4a63SDavid du Colombier }
1348ccd4a63SDavid du Colombier f->name = smbestrdup(path);
1358ccd4a63SDavid du Colombier f->sf = sf;
1368ccd4a63SDavid du Colombier sf = nil;
1378ccd4a63SDavid du Colombier f->share = share;
1388ccd4a63SDavid du Colombier f->p9mode = p9mode;
1398ccd4a63SDavid du Colombier f->t = t;
1408ccd4a63SDavid du Colombier if (s->fidmap == nil)
1418ccd4a63SDavid du Colombier s->fidmap = smbidmapnew();
1428ccd4a63SDavid du Colombier *fidp = smbidmapadd(s->fidmap, f);
14386a363ceSDavid du Colombier //smblogprint(h->command, "REPLY:\n t->id=0x%ux fid=%d path=%s\n", t->id, *fidp, path);
1448ccd4a63SDavid du Colombier smblogprintif(smbglobals.log.fids, "openfile: 0x%.4ux/0x%.4ux %s\n", t->id, *fidp, path);
1458ccd4a63SDavid du Colombier if (actionp)
1468ccd4a63SDavid du Colombier *actionp = action;
1478ccd4a63SDavid du Colombier if (dp) {
1488ccd4a63SDavid du Colombier *dp = d;
1498ccd4a63SDavid du Colombier d = nil;
1508ccd4a63SDavid du Colombier }
1518ccd4a63SDavid du Colombier done:
1528ccd4a63SDavid du Colombier if (sf)
1538ccd4a63SDavid du Colombier smbsharedfileput(nil, sf, share);
1548ccd4a63SDavid du Colombier free(d);
1558ccd4a63SDavid du Colombier free(fullpath);
1568ccd4a63SDavid du Colombier return f;
1578ccd4a63SDavid du Colombier }
1588ccd4a63SDavid du Colombier
1598ccd4a63SDavid du Colombier SmbProcessResult
smbcomopenandx(SmbSession * s,SmbHeader * h,uchar * pdata,SmbBuffer * b)1608ccd4a63SDavid du Colombier smbcomopenandx(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
1618ccd4a63SDavid du Colombier {
1628ccd4a63SDavid du Colombier uchar andxcommand;
1638ccd4a63SDavid du Colombier ushort andxoffset, flags, mode, sattr, attr;
1648ccd4a63SDavid du Colombier ulong createtime;
1658ccd4a63SDavid du Colombier ushort ofun;
1668ccd4a63SDavid du Colombier ulong createsize, timeout;
1678ccd4a63SDavid du Colombier char *path = nil;
1688ccd4a63SDavid du Colombier ulong andxoffsetfixupoffset;
1698ccd4a63SDavid du Colombier SmbProcessResult pr;
1708ccd4a63SDavid du Colombier ushort action;
1718ccd4a63SDavid du Colombier Dir *d = nil;
1728ccd4a63SDavid du Colombier SmbFile *f;
1738ccd4a63SDavid du Colombier SmbTree *t;
1748ccd4a63SDavid du Colombier ushort fid;
1758ccd4a63SDavid du Colombier
1768ccd4a63SDavid du Colombier if (!smbcheckwordcount("comopenandx", h, 15))
1778ccd4a63SDavid du Colombier return SmbProcessResultFormat;
1788ccd4a63SDavid du Colombier
1798ccd4a63SDavid du Colombier andxcommand = *pdata++;
1808ccd4a63SDavid du Colombier pdata++;
1818ccd4a63SDavid du Colombier andxoffset = smbnhgets(pdata); pdata += 2;
1828ccd4a63SDavid du Colombier flags = smbnhgets(pdata); pdata += 2;
1838ccd4a63SDavid du Colombier mode = smbnhgets(pdata); pdata += 2;
1848ccd4a63SDavid du Colombier sattr = smbnhgets(pdata); pdata += 2;
1858ccd4a63SDavid du Colombier attr = smbnhgets(pdata); pdata += 2;
1868ccd4a63SDavid du Colombier createtime = smbnhgetl(pdata); pdata += 4;
1878ccd4a63SDavid du Colombier ofun = smbnhgets(pdata); pdata += 2;
1888ccd4a63SDavid du Colombier createsize = smbnhgetl(pdata); pdata += 4;
1898ccd4a63SDavid du Colombier timeout = smbnhgetl(pdata); pdata += 4;
1908ccd4a63SDavid du Colombier pdata += 4;
1918ccd4a63SDavid du Colombier USED(pdata);
1928ccd4a63SDavid du Colombier if (!smbbuffergetstring(b, h, SMB_STRING_PATH, &path)) {
1938ccd4a63SDavid du Colombier pr = SmbProcessResultFormat;
1948ccd4a63SDavid du Colombier goto done;
1958ccd4a63SDavid du Colombier }
1968ccd4a63SDavid du Colombier
1978ccd4a63SDavid du Colombier smbloglock();
1988ccd4a63SDavid du Colombier smblogprint(h->command, "flags 0x%.4ux", flags);
1998ccd4a63SDavid du Colombier if (flags & SMB_OPEN_FLAGS_ADDITIONAL)
2008ccd4a63SDavid du Colombier smblogprint(h->command, " additional");
2018ccd4a63SDavid du Colombier if (flags & SMB_OPEN_FLAGS_OPLOCK)
2028ccd4a63SDavid du Colombier smblogprint(h->command, " oplock");
2038ccd4a63SDavid du Colombier if (flags & SMB_OPEN_FLAGS_OPBATCH)
2048ccd4a63SDavid du Colombier smblogprint(h->command, " opbatch");
2058ccd4a63SDavid du Colombier smblogprint(h->command, "\n");
2068ccd4a63SDavid du Colombier smblogprint(h->command, "mode 0x%.4ux", mode);
2078ccd4a63SDavid du Colombier switch ((mode >> SMB_OPEN_MODE_ACCESS_SHIFT) & SMB_OPEN_MODE_ACCESS_MASK) {
2088ccd4a63SDavid du Colombier case OREAD:
2098ccd4a63SDavid du Colombier smblogprint(h->command, " OREAD");
2108ccd4a63SDavid du Colombier break;
2118ccd4a63SDavid du Colombier case OWRITE:
2128ccd4a63SDavid du Colombier smblogprint(h->command, " OWRITE");
2138ccd4a63SDavid du Colombier break;
2148ccd4a63SDavid du Colombier case ORDWR:
2158ccd4a63SDavid du Colombier smblogprint(h->command, " ORDWR");
2168ccd4a63SDavid du Colombier break;
2178ccd4a63SDavid du Colombier case OEXEC:
2188ccd4a63SDavid du Colombier smblogprint(h->command, " OEXEC");
2198ccd4a63SDavid du Colombier break;
2208ccd4a63SDavid du Colombier }
2218ccd4a63SDavid du Colombier switch ((mode >> SMB_OPEN_MODE_SHARE_SHIFT) & SMB_OPEN_MODE_SHARE_MASK) {
2228ccd4a63SDavid du Colombier case SMB_OPEN_MODE_SHARE_COMPATIBILITY:
2238ccd4a63SDavid du Colombier smblogprint(h->command, " compatinility");
2248ccd4a63SDavid du Colombier break;
2258ccd4a63SDavid du Colombier case SMB_OPEN_MODE_SHARE_EXCLUSIVE:
2268ccd4a63SDavid du Colombier smblogprint(h->command, " exclusive");
2278ccd4a63SDavid du Colombier break;
2288ccd4a63SDavid du Colombier case SMB_OPEN_MODE_SHARE_DENY_WRITE:
2298ccd4a63SDavid du Colombier smblogprint(h->command, " deny write");
2308ccd4a63SDavid du Colombier break;
2318ccd4a63SDavid du Colombier case SMB_OPEN_MODE_SHARE_DENY_READOREXEC:
2328ccd4a63SDavid du Colombier smblogprint(h->command, " deny readorxec");
2338ccd4a63SDavid du Colombier break;
2348ccd4a63SDavid du Colombier case SMB_OPEN_MODE_SHARE_DENY_NONE:
2358ccd4a63SDavid du Colombier smblogprint(h->command, " deny none");
2368ccd4a63SDavid du Colombier break;
2378ccd4a63SDavid du Colombier }
2388ccd4a63SDavid du Colombier if (mode & SMB_OPEN_MODE_WRITE_THROUGH)
2398ccd4a63SDavid du Colombier smblogprint(h->command, " write through");
2408ccd4a63SDavid du Colombier smblogprint(h->command, "\n");
2418ccd4a63SDavid du Colombier smblogprint(h->command, "sattr 0x%.4ux", sattr);
2428ccd4a63SDavid du Colombier smblogprintattr(h->command, sattr);
2438ccd4a63SDavid du Colombier smblogprint(h->command, "\n");
2448ccd4a63SDavid du Colombier smblogprint(h->command, "attr 0x%.4ux", attr);
2458ccd4a63SDavid du Colombier smblogprintattr(h->command, attr);
2468ccd4a63SDavid du Colombier smblogprint(h->command, "\n");
2478ccd4a63SDavid du Colombier smblogprint(h->command, "createtime 0x%.8lux\n", createtime);
2488ccd4a63SDavid du Colombier smblogprint(h->command, "ofun 0x%.4ux", ofun);
2498ccd4a63SDavid du Colombier if (ofun & SMB_OFUN_NOEXIST_CREATE)
2508ccd4a63SDavid du Colombier smblogprint(h->command, " noexistscreate");
2518ccd4a63SDavid du Colombier else
2528ccd4a63SDavid du Colombier smblogprint(h->command, " noexistfail");
2538ccd4a63SDavid du Colombier switch ((ofun >> SMB_OFUN_EXIST_SHIFT) & SMB_OFUN_EXIST_MASK) {
2548ccd4a63SDavid du Colombier case SMB_OFUN_EXIST_FAIL:
2558ccd4a63SDavid du Colombier smblogprint(h->command, " existfail");
2568ccd4a63SDavid du Colombier break;
2578ccd4a63SDavid du Colombier case SMB_OFUN_EXIST_OPEN:
2588ccd4a63SDavid du Colombier smblogprint(h->command, " existopen");
2598ccd4a63SDavid du Colombier break;
2608ccd4a63SDavid du Colombier case SMB_OFUN_EXIST_TRUNCATE:
2618ccd4a63SDavid du Colombier smblogprint(h->command, " existtruncate");
2628ccd4a63SDavid du Colombier break;
2638ccd4a63SDavid du Colombier }
2648ccd4a63SDavid du Colombier smblogprint(h->command, "\n");
2658ccd4a63SDavid du Colombier smblogprint(h->command, "createsize 0x%.8lux\n", createsize);
2668ccd4a63SDavid du Colombier smblogprint(h->command, "timeout 0x%.8lux\n", timeout);
2678ccd4a63SDavid du Colombier smblogprint(h->command, "path %s\n", path);
2688ccd4a63SDavid du Colombier smblogunlock();
2698ccd4a63SDavid du Colombier
2708ccd4a63SDavid du Colombier t = smbidmapfind(s->tidmap, h->tid);
2718ccd4a63SDavid du Colombier if (t == nil) {
2728ccd4a63SDavid du Colombier smbseterror(s, ERRSRV, ERRinvtid);
2738ccd4a63SDavid du Colombier goto errordone;
2748ccd4a63SDavid du Colombier }
2758ccd4a63SDavid du Colombier
2768ccd4a63SDavid du Colombier f = openfile(s, t, path, mode, attr, ofun, 0, createsize, &fid, &d, &action);
2778ccd4a63SDavid du Colombier if (f == nil) {
2788ccd4a63SDavid du Colombier pr = SmbProcessResultError;
2798ccd4a63SDavid du Colombier goto done;
2808ccd4a63SDavid du Colombier }
2818ccd4a63SDavid du Colombier h->wordcount = 15;
2828ccd4a63SDavid du Colombier if (!smbbufferputandxheader(s->response, h, &s->peerinfo, andxcommand, &andxoffsetfixupoffset)
2838ccd4a63SDavid du Colombier || !smbbufferputs(s->response, fid)
2848ccd4a63SDavid du Colombier || !smbbufferputs(s->response, smbplan9mode2dosattr(d->mode))
2858ccd4a63SDavid du Colombier || !smbbufferputl(s->response, smbplan9time2utime(d->mtime, s->tzoff))
2868ccd4a63SDavid du Colombier || !smbbufferputl(s->response, smbplan9length2size32(d->length))
2878ccd4a63SDavid du Colombier || !smbbufferputs(s->response, smbplan9mode2dosattr(d->mode)) // probbaly bogus
2888ccd4a63SDavid du Colombier || !smbbufferputs(s->response, 0) // all files are files
2898ccd4a63SDavid du Colombier || !smbbufferputs(s->response, 0) // pipe state
2908ccd4a63SDavid du Colombier || !smbbufferputs(s->response, action)
2918ccd4a63SDavid du Colombier || !smbbufferputl(s->response, 0) // fileID
2928ccd4a63SDavid du Colombier || !smbbufferputs(s->response, 0)
2938ccd4a63SDavid du Colombier || !smbbufferputs(s->response, 0)) { // bytecount 0
2948ccd4a63SDavid du Colombier smbfileclose(s, f);
2958ccd4a63SDavid du Colombier pr = SmbProcessResultMisc;
2968ccd4a63SDavid du Colombier goto done;
2978ccd4a63SDavid du Colombier }
2988ccd4a63SDavid du Colombier if (andxcommand != SMB_COM_NO_ANDX_COMMAND)
2998ccd4a63SDavid du Colombier pr = smbchaincommand(s, h, andxoffsetfixupoffset, andxcommand, andxoffset, b);
3008ccd4a63SDavid du Colombier else
3018ccd4a63SDavid du Colombier pr = SmbProcessResultReply;
3028ccd4a63SDavid du Colombier goto done;
3038ccd4a63SDavid du Colombier errordone:
3048ccd4a63SDavid du Colombier pr = SmbProcessResultError;
3058ccd4a63SDavid du Colombier done:
3068ccd4a63SDavid du Colombier free(path);
3078ccd4a63SDavid du Colombier free(d);
3088ccd4a63SDavid du Colombier return pr;
3098ccd4a63SDavid du Colombier }
3108ccd4a63SDavid du Colombier
3118ccd4a63SDavid du Colombier SmbProcessResult
smbcomopen(SmbSession * s,SmbHeader * h,uchar * pdata,SmbBuffer * b)3128ccd4a63SDavid du Colombier smbcomopen(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
3138ccd4a63SDavid du Colombier {
3148ccd4a63SDavid du Colombier uchar fmt;
3158ccd4a63SDavid du Colombier char *path;
3168ccd4a63SDavid du Colombier ushort mode, attr;
3178ccd4a63SDavid du Colombier SmbTree *t;
3188ccd4a63SDavid du Colombier ushort fid;
3198ccd4a63SDavid du Colombier Dir *d = nil;
3208ccd4a63SDavid du Colombier SmbFile *f;
3218ccd4a63SDavid du Colombier SmbProcessResult pr;
3228ccd4a63SDavid du Colombier
3238ccd4a63SDavid du Colombier if (!smbcheckwordcount("comopen", h, 2))
3248ccd4a63SDavid du Colombier return SmbProcessResultFormat;
3258ccd4a63SDavid du Colombier mode = smbnhgets(pdata);
3268ccd4a63SDavid du Colombier attr = smbnhgets(pdata + 2);
3278ccd4a63SDavid du Colombier if (!smbbuffergetb(b, &fmt)
3288ccd4a63SDavid du Colombier || fmt != 4
3298ccd4a63SDavid du Colombier || !smbbuffergetstring(b, h, SMB_STRING_PATH, &path)) {
3308ccd4a63SDavid du Colombier pr = SmbProcessResultFormat;
3318ccd4a63SDavid du Colombier goto done;
3328ccd4a63SDavid du Colombier }
3338ccd4a63SDavid du Colombier t = smbidmapfind(s->tidmap, h->tid);
3348ccd4a63SDavid du Colombier if (t == nil) {
3358ccd4a63SDavid du Colombier smbseterror(s, ERRSRV, ERRinvtid);
3368ccd4a63SDavid du Colombier error:
3378ccd4a63SDavid du Colombier pr = SmbProcessResultError;
3388ccd4a63SDavid du Colombier goto done;
3398ccd4a63SDavid du Colombier }
3408ccd4a63SDavid du Colombier f = openfile(s, t, path, mode, attr,
3418ccd4a63SDavid du Colombier SMB_OFUN_EXIST_OPEN << SMB_OFUN_EXIST_SHIFT,
3428ccd4a63SDavid du Colombier 0, 0, &fid, &d, nil);
3438ccd4a63SDavid du Colombier if (f == nil)
3448ccd4a63SDavid du Colombier goto error;
3458ccd4a63SDavid du Colombier h->wordcount = 7;
3468ccd4a63SDavid du Colombier if (!smbbufferputheader(s->response, h, &s->peerinfo)
3478ccd4a63SDavid du Colombier || !smbbufferputs(s->response, fid)
3488ccd4a63SDavid du Colombier || !smbbufferputs(s->response, smbplan9mode2dosattr(d->mode))
3498ccd4a63SDavid du Colombier || !smbbufferputl(s->response, smbplan9time2utime(d->mtime, s->tzoff))
3508ccd4a63SDavid du Colombier || !smbbufferputl(s->response, smbplan9length2size32(d->length))
3518ccd4a63SDavid du Colombier || !smbbufferputs(s->response, 2) // lies - this should be the actual access allowed
3528ccd4a63SDavid du Colombier || !smbbufferputs(s->response, 0))
3538ccd4a63SDavid du Colombier pr = SmbProcessResultMisc;
3548ccd4a63SDavid du Colombier else
3558ccd4a63SDavid du Colombier pr = SmbProcessResultReply;
3568ccd4a63SDavid du Colombier done:
3578ccd4a63SDavid du Colombier free(path);
3588ccd4a63SDavid du Colombier free(d);
3598ccd4a63SDavid du Colombier return pr;
3608ccd4a63SDavid du Colombier }
3618ccd4a63SDavid du Colombier
36286a363ceSDavid du Colombier
36386a363ceSDavid du Colombier /*
36486a363ceSDavid du Colombier smb_com SMBcreate smb_com SMBcreate
36586a363ceSDavid du Colombier smb_wct 3 smb_wct 1
36686a363ceSDavid du Colombier smb_vwv[0] attribute smb_vwv[0] file handle
36786a363ceSDavid du Colombier smb_vwv[1] time low smb_bcc 0
36886a363ceSDavid du Colombier smb_vwv[2] time high
36986a363ceSDavid du Colombier smb_bcc min = 2
37086a363ceSDavid du Colombier smb_buf[] ASCII -- 04
37186a363ceSDavid du Colombier file pathname
37286a363ceSDavid du Colombier */
37386a363ceSDavid du Colombier
37486a363ceSDavid du Colombier SmbProcessResult
smbcomcreate(SmbSession * s,SmbHeader * h,uchar * pdata,SmbBuffer * b)37586a363ceSDavid du Colombier smbcomcreate(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
37686a363ceSDavid du Colombier {
37786a363ceSDavid du Colombier int ofun, attr, mode;
37886a363ceSDavid du Colombier long createtime;
37986a363ceSDavid du Colombier char *path;
38086a363ceSDavid du Colombier uchar fmt;
38186a363ceSDavid du Colombier SmbFile *f;
38286a363ceSDavid du Colombier SmbTree *t;
38386a363ceSDavid du Colombier ushort fid;
38486a363ceSDavid du Colombier SmbProcessResult pr;
38586a363ceSDavid du Colombier
38686a363ceSDavid du Colombier path = nil;
38786a363ceSDavid du Colombier if (!smbcheckwordcount("comcreate", h, 3))
38886a363ceSDavid du Colombier return SmbProcessResultFormat;
38986a363ceSDavid du Colombier
39086a363ceSDavid du Colombier smblogprint(h->command, "tid=%d\n", h->tid);
39186a363ceSDavid du Colombier attr = smbnhgets(pdata); pdata += 2;
39286a363ceSDavid du Colombier createtime = smbnhgetl(pdata);
39386a363ceSDavid du Colombier if (!smbbuffergetb(b, &fmt) || fmt != 0x04 ||
39486a363ceSDavid du Colombier !smbbuffergetstring(b, h, SMB_STRING_PATH, &path)){
39586a363ceSDavid du Colombier pr = SmbProcessResultError;
39686a363ceSDavid du Colombier goto done;
39786a363ceSDavid du Colombier }
39886a363ceSDavid du Colombier
39986a363ceSDavid du Colombier smbloglock();
40086a363ceSDavid du Colombier smblogprint(h->command, "path %s\n", path);
40186a363ceSDavid du Colombier smblogprint(h->command, "attr 0x%.4ux", attr);
40286a363ceSDavid du Colombier smblogprintattr(h->command, attr);
40386a363ceSDavid du Colombier smblogprint(h->command, "\n");
40486a363ceSDavid du Colombier smblogprint(h->command, "createtime 0x%.8lux\n", createtime);
40586a363ceSDavid du Colombier smblogunlock();
40686a363ceSDavid du Colombier
40786a363ceSDavid du Colombier t = smbidmapfind(s->tidmap, h->tid);
40886a363ceSDavid du Colombier if (t == nil) {
40986a363ceSDavid du Colombier pr = SmbProcessResultError;
41086a363ceSDavid du Colombier goto done;
41186a363ceSDavid du Colombier }
41286a363ceSDavid du Colombier
41386a363ceSDavid du Colombier mode = (ORDWR<<SMB_OPEN_MODE_ACCESS_SHIFT) | // SFS: FIXME: should be OWRITE?
41486a363ceSDavid du Colombier (SMB_OPEN_MODE_SHARE_EXCLUSIVE<<SMB_OPEN_MODE_SHARE_SHIFT);
41586a363ceSDavid du Colombier ofun = SMB_OFUN_NOEXIST_CREATE|(SMB_OFUN_EXIST_FAIL<<SMB_OFUN_EXIST_SHIFT);
41686a363ceSDavid du Colombier f = openfile(s, t, path, mode, attr, ofun, SMB_CO_FILE, 0, &fid, nil, nil);
41786a363ceSDavid du Colombier if (f == nil) {
41886a363ceSDavid du Colombier pr = SmbProcessResultError;
41986a363ceSDavid du Colombier goto done;
42086a363ceSDavid du Colombier }
42186a363ceSDavid du Colombier
42286a363ceSDavid du Colombier h->wordcount = 1; // SFS: FIXME: unsure of this constant, maybe should be 3
42386a363ceSDavid du Colombier if (!smbbufferputheader(s->response, h, &s->peerinfo)
42486a363ceSDavid du Colombier || !smbbufferputs(s->response, fid)
42586a363ceSDavid du Colombier || !smbbufferputs(s->response, 0)){ // bytecount 0
42686a363ceSDavid du Colombier pr = SmbProcessResultMisc;
42786a363ceSDavid du Colombier goto done;
42886a363ceSDavid du Colombier }
42986a363ceSDavid du Colombier pr = SmbProcessResultReply;
43086a363ceSDavid du Colombier goto done;
43186a363ceSDavid du Colombier
43286a363ceSDavid du Colombier done:
43386a363ceSDavid du Colombier free(path);
43486a363ceSDavid du Colombier return pr;
43586a363ceSDavid du Colombier }
43686a363ceSDavid du Colombier
43786a363ceSDavid du Colombier
4388ccd4a63SDavid du Colombier typedef struct SmbSblut {
4398ccd4a63SDavid du Colombier char *s;
4408ccd4a63SDavid du Colombier ulong mask;
4418ccd4a63SDavid du Colombier } SmbSblut;
4428ccd4a63SDavid du Colombier
4438ccd4a63SDavid du Colombier static SmbSblut dasblut[] = {
4448ccd4a63SDavid du Colombier { "SMB_DA_SPECIFIC_READ_DATA", SMB_DA_SPECIFIC_READ_DATA },
4458ccd4a63SDavid du Colombier { "SMB_DA_SPECIFIC_WRITE_DATA", SMB_DA_SPECIFIC_WRITE_DATA },
4468ccd4a63SDavid du Colombier { "SMB_DA_SPECIFIC_APPEND_DATA", SMB_DA_SPECIFIC_APPEND_DATA },
4478ccd4a63SDavid du Colombier { "SMB_DA_SPECIFIC_READ_EA", SMB_DA_SPECIFIC_READ_EA },
4488ccd4a63SDavid du Colombier { "SMB_DA_SPECIFIC_WRITE_EA", SMB_DA_SPECIFIC_WRITE_EA },
4498ccd4a63SDavid du Colombier { "SMB_DA_SPECIFIC_EXECUTE", SMB_DA_SPECIFIC_EXECUTE },
4508ccd4a63SDavid du Colombier { "SMB_DA_SPECIFIC_DELETE_CHILD", SMB_DA_SPECIFIC_DELETE_CHILD },
4518ccd4a63SDavid du Colombier { "SMB_DA_SPECIFIC_READ_ATTRIBUTES", SMB_DA_SPECIFIC_READ_ATTRIBUTES },
4528ccd4a63SDavid du Colombier { "SMB_DA_SPECIFIC_WRITE_ATTRIBUTES", SMB_DA_SPECIFIC_WRITE_ATTRIBUTES },
4538ccd4a63SDavid du Colombier { "SMB_DA_STANDARD_DELETE_ACCESS", SMB_DA_STANDARD_DELETE_ACCESS },
4548ccd4a63SDavid du Colombier { "SMB_DA_STANDARD_READ_CONTROL_ACCESS", SMB_DA_STANDARD_READ_CONTROL_ACCESS },
4558ccd4a63SDavid du Colombier { "SMB_DA_STANDARD_WRITE_DAC_ACCESS", SMB_DA_STANDARD_WRITE_DAC_ACCESS },
4568ccd4a63SDavid du Colombier { "SMB_DA_STANDARD_WRITE_OWNER_ACCESS", SMB_DA_STANDARD_WRITE_OWNER_ACCESS },
4578ccd4a63SDavid du Colombier { "SMB_DA_STANDARD_SYNCHRONIZE_ACCESS", SMB_DA_STANDARD_SYNCHRONIZE_ACCESS },
4588ccd4a63SDavid du Colombier { "SMB_DA_GENERIC_ALL_ACCESS", SMB_DA_GENERIC_ALL_ACCESS },
4598ccd4a63SDavid du Colombier { "SMB_DA_GENERIC_EXECUTE_ACCESS", SMB_DA_GENERIC_EXECUTE_ACCESS },
4608ccd4a63SDavid du Colombier { "SMB_DA_GENERIC_WRITE_ACCESS", SMB_DA_GENERIC_WRITE_ACCESS },
4618ccd4a63SDavid du Colombier { "SMB_DA_GENERIC_READ_ACCESS", SMB_DA_GENERIC_READ_ACCESS },
4628ccd4a63SDavid du Colombier { 0 }
4638ccd4a63SDavid du Colombier };
4648ccd4a63SDavid du Colombier
4658ccd4a63SDavid du Colombier static SmbSblut efasblut[] = {
4668ccd4a63SDavid du Colombier { "SMB_ATTR_READ_ONLY", SMB_ATTR_READ_ONLY },
4678ccd4a63SDavid du Colombier { "SMB_ATTR_HIDDEN", SMB_ATTR_HIDDEN },
4688ccd4a63SDavid du Colombier { "SMB_ATTR_SYSTEM", SMB_ATTR_SYSTEM },
4698ccd4a63SDavid du Colombier { "SMB_ATTR_DIRECTORY", SMB_ATTR_DIRECTORY },
4708ccd4a63SDavid du Colombier { "SMB_ATTR_ARCHIVE", SMB_ATTR_ARCHIVE },
4718ccd4a63SDavid du Colombier { "SMB_ATTR_NORMAL", SMB_ATTR_NORMAL },
4728ccd4a63SDavid du Colombier { "SMB_ATTR_COMPRESSED", SMB_ATTR_COMPRESSED },
4738ccd4a63SDavid du Colombier { "SMB_ATTR_TEMPORARY", SMB_ATTR_TEMPORARY },
4748ccd4a63SDavid du Colombier { "SMB_ATTR_WRITETHROUGH", SMB_ATTR_WRITETHROUGH },
4758ccd4a63SDavid du Colombier { "SMB_ATTR_NO_BUFFERING", SMB_ATTR_NO_BUFFERING },
4768ccd4a63SDavid du Colombier { "SMB_ATTR_RANDOM_ACCESS", SMB_ATTR_RANDOM_ACCESS },
4778ccd4a63SDavid du Colombier { 0 }
4788ccd4a63SDavid du Colombier };
4798ccd4a63SDavid du Colombier
4808ccd4a63SDavid du Colombier static SmbSblut sasblut[] = {
4818ccd4a63SDavid du Colombier { "SMB_SA_SHARE_READ", SMB_SA_SHARE_READ },
4828ccd4a63SDavid du Colombier { "SMB_SA_SHARE_WRITE", SMB_SA_SHARE_WRITE },
4838ccd4a63SDavid du Colombier { "SMB_SA_SHARE_DELETE", SMB_SA_SHARE_DELETE },
4848ccd4a63SDavid du Colombier { "SMB_SA_NO_SHARE", SMB_SA_NO_SHARE },
4858ccd4a63SDavid du Colombier { 0 }
4868ccd4a63SDavid du Colombier };
4878ccd4a63SDavid du Colombier
4888ccd4a63SDavid du Colombier static SmbSblut cosblut[] = {
4898ccd4a63SDavid du Colombier { "SMB_CO_DIRECTORY", SMB_CO_DIRECTORY },
4908ccd4a63SDavid du Colombier { "SMB_CO_WRITETHROUGH", SMB_CO_WRITETHROUGH },
4918ccd4a63SDavid du Colombier { "SMB_CO_SEQUENTIAL_ONLY", SMB_CO_SEQUENTIAL_ONLY },
4928ccd4a63SDavid du Colombier { "SMB_CO_FILE", SMB_CO_FILE },
4938ccd4a63SDavid du Colombier { "SMB_CO_NO_EA_KNOWLEDGE", SMB_CO_NO_EA_KNOWLEDGE },
4948ccd4a63SDavid du Colombier { "SMB_CO_EIGHT_DOT_THREE_ONLY", SMB_CO_EIGHT_DOT_THREE_ONLY },
4958ccd4a63SDavid du Colombier { "SMB_CO_RANDOM_ACCESS", SMB_CO_RANDOM_ACCESS },
4968ccd4a63SDavid du Colombier { "SMB_CO_DELETE_ON_CLOSE", SMB_CO_DELETE_ON_CLOSE },
4978ccd4a63SDavid du Colombier { 0 }
4988ccd4a63SDavid du Colombier };
4998ccd4a63SDavid du Colombier
5008ccd4a63SDavid du Colombier static SmbSlut cdslut[] = {
5018ccd4a63SDavid du Colombier { "SMB_CD_SUPERCEDE", SMB_CD_SUPERCEDE },
5028ccd4a63SDavid du Colombier { "SMB_CD_OPEN", SMB_CD_OPEN },
5038ccd4a63SDavid du Colombier { "SMB_CD_CREATE", SMB_CD_CREATE },
5048ccd4a63SDavid du Colombier { "SMB_CD_OPEN_IF", SMB_CD_OPEN_IF },
5058ccd4a63SDavid du Colombier { "SMB_CD_OVERWRITE", SMB_CD_OVERWRITE },
5068ccd4a63SDavid du Colombier { "SMB_CD_OVERWRITE_IF", SMB_CD_OVERWRITE_IF },
5078ccd4a63SDavid du Colombier { 0 }
5088ccd4a63SDavid du Colombier };
5098ccd4a63SDavid du Colombier
5108ccd4a63SDavid du Colombier static void
smbsblutlogprint(uchar cmd,SmbSblut * sblut,ulong mask)5118ccd4a63SDavid du Colombier smbsblutlogprint(uchar cmd, SmbSblut *sblut, ulong mask)
5128ccd4a63SDavid du Colombier {
5138ccd4a63SDavid du Colombier while (sblut->s) {
5148ccd4a63SDavid du Colombier if (mask && (sblut->mask & mask) || (mask == 0 && sblut->mask == 0))
5158ccd4a63SDavid du Colombier smblogprint(cmd, " %s", sblut->s);
5168ccd4a63SDavid du Colombier sblut++;
5178ccd4a63SDavid du Colombier }
5188ccd4a63SDavid du Colombier }
5198ccd4a63SDavid du Colombier
5208ccd4a63SDavid du Colombier SmbProcessResult
smbcomntcreateandx(SmbSession * s,SmbHeader * h,uchar * pdata,SmbBuffer * b)5218ccd4a63SDavid du Colombier smbcomntcreateandx(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
5228ccd4a63SDavid du Colombier {
5238ccd4a63SDavid du Colombier uchar andxcommand;
5248ccd4a63SDavid du Colombier ushort andxoffset;
5258ccd4a63SDavid du Colombier char *path = nil;
5268ccd4a63SDavid du Colombier SmbProcessResult pr;
5278ccd4a63SDavid du Colombier ulong namelength;
5288ccd4a63SDavid du Colombier ulong flags;
5298ccd4a63SDavid du Colombier ulong rootdirectoryfid, desiredaccess;
5308ccd4a63SDavid du Colombier uvlong allocationsize;
5318ccd4a63SDavid du Colombier ulong extfileattributes, shareaccess, createdisposition, createoptions, impersonationlevel;
5328ccd4a63SDavid du Colombier uchar securityflags;
5338ccd4a63SDavid du Colombier int p9mode;
5348ccd4a63SDavid du Colombier int sharemode;
5358ccd4a63SDavid du Colombier ushort mode;
5368ccd4a63SDavid du Colombier SmbTree *t;
5378ccd4a63SDavid du Colombier ushort ofun;
5388ccd4a63SDavid du Colombier SmbFile *f;
5398ccd4a63SDavid du Colombier ushort fid;
5408ccd4a63SDavid du Colombier Dir *d = nil;
5418ccd4a63SDavid du Colombier ushort action;
5428ccd4a63SDavid du Colombier uvlong mtime;
5438ccd4a63SDavid du Colombier ulong andxoffsetfixup;
5448ccd4a63SDavid du Colombier
5458ccd4a63SDavid du Colombier if (!smbcheckwordcount("comntcreateandx", h, 24))
5468ccd4a63SDavid du Colombier return SmbProcessResultFormat;
5478ccd4a63SDavid du Colombier
5488ccd4a63SDavid du Colombier andxcommand = *pdata++;
5498ccd4a63SDavid du Colombier pdata++;
5508ccd4a63SDavid du Colombier andxoffset = smbnhgets(pdata); pdata += 2;
5518ccd4a63SDavid du Colombier pdata++;
5528ccd4a63SDavid du Colombier namelength = smbnhgets(pdata); pdata += 2;
5538ccd4a63SDavid du Colombier flags = smbnhgetl(pdata); pdata += 4;
5548ccd4a63SDavid du Colombier rootdirectoryfid = smbnhgetl(pdata); pdata += 4;
5558ccd4a63SDavid du Colombier desiredaccess = smbnhgetl(pdata); pdata += 4;
5568ccd4a63SDavid du Colombier allocationsize = smbnhgetv(pdata); pdata += 8;
5578ccd4a63SDavid du Colombier extfileattributes = smbnhgetl(pdata); pdata += 4;
5588ccd4a63SDavid du Colombier shareaccess = smbnhgetl(pdata); pdata += 4;
5598ccd4a63SDavid du Colombier createdisposition = smbnhgetl(pdata); pdata += 4;
5608ccd4a63SDavid du Colombier createoptions = smbnhgetl(pdata); pdata += 4;
5618ccd4a63SDavid du Colombier impersonationlevel = smbnhgetl(pdata); pdata += 4;
5628ccd4a63SDavid du Colombier securityflags = *pdata++;
5638ccd4a63SDavid du Colombier USED(pdata);
5648ccd4a63SDavid du Colombier
5658ccd4a63SDavid du Colombier if (!smbbuffergetstring(b, h, SMB_STRING_PATH, &path)) {
5668ccd4a63SDavid du Colombier pr = SmbProcessResultFormat;
5678ccd4a63SDavid du Colombier goto done;
5688ccd4a63SDavid du Colombier }
5698ccd4a63SDavid du Colombier
5708ccd4a63SDavid du Colombier smblogprint(h->command, "namelength %d\n", namelength);
5718ccd4a63SDavid du Colombier smblogprint(h->command, "flags 0x%.8lux\n", flags);
5728ccd4a63SDavid du Colombier smblogprint(h->command, "rootdirectoryfid %lud\n", rootdirectoryfid);
5738ccd4a63SDavid du Colombier smblogprint(h->command, "desiredaccess 0x%.8lux", desiredaccess);
5748ccd4a63SDavid du Colombier smbsblutlogprint(h->command, dasblut, desiredaccess);
5758ccd4a63SDavid du Colombier smblogprint(h->command, "\n");
5768ccd4a63SDavid du Colombier smblogprint(h->command, "allocationsize %llud\n", allocationsize);
5778ccd4a63SDavid du Colombier smblogprint(h->command, "extfileattributes 0x%.8lux", extfileattributes);
5788ccd4a63SDavid du Colombier smbsblutlogprint(h->command, efasblut, extfileattributes);
5798ccd4a63SDavid du Colombier smblogprint(h->command, "\n");
5808ccd4a63SDavid du Colombier smblogprint(h->command, "shareaccess 0x%.8lux", shareaccess);
5818ccd4a63SDavid du Colombier smbsblutlogprint(h->command, sasblut, shareaccess);
5828ccd4a63SDavid du Colombier smblogprint(h->command, "\n");
5838ccd4a63SDavid du Colombier smblogprint(h->command, "createdisposition 0x%.8lux %s\n",
5848ccd4a63SDavid du Colombier createdisposition, smbrevslut(cdslut, createdisposition));
5858ccd4a63SDavid du Colombier smblogprint(h->command, "createoptions 0x%.8lux", createoptions);
5868ccd4a63SDavid du Colombier smbsblutlogprint(h->command, cosblut, createoptions);
5878ccd4a63SDavid du Colombier smblogprint(h->command, "\n");
5888ccd4a63SDavid du Colombier smblogprint(h->command, "impersonationlevel 0x%.8lux\n", impersonationlevel);
5898ccd4a63SDavid du Colombier smblogprint(h->command, "securityflags 0x%.2ux\n", securityflags);
5908ccd4a63SDavid du Colombier smblogprint(h->command, "path %s\n", path);
5918ccd4a63SDavid du Colombier
5928ccd4a63SDavid du Colombier if (rootdirectoryfid != 0) {
5938ccd4a63SDavid du Colombier smblogprint(-1, "smbcomntcreateandx: fid relative not implemented\n");
5948ccd4a63SDavid du Colombier goto unimp;
5958ccd4a63SDavid du Colombier }
5968ccd4a63SDavid du Colombier
59786a363ceSDavid du Colombier if (desiredaccess & SMB_DA_GENERIC_MASK)
59886a363ceSDavid du Colombier switch (desiredaccess & SMB_DA_GENERIC_MASK){
59986a363ceSDavid du Colombier case SMB_DA_GENERIC_READ_ACCESS:
60086a363ceSDavid du Colombier p9mode = OREAD;
60186a363ceSDavid du Colombier break;
60286a363ceSDavid du Colombier case SMB_DA_GENERIC_WRITE_ACCESS:
60386a363ceSDavid du Colombier p9mode = OWRITE;
60486a363ceSDavid du Colombier break;
60586a363ceSDavid du Colombier case SMB_DA_GENERIC_ALL_ACCESS:
60686a363ceSDavid du Colombier p9mode = ORDWR;
60786a363ceSDavid du Colombier break;
60886a363ceSDavid du Colombier case SMB_DA_GENERIC_EXECUTE_ACCESS:
60986a363ceSDavid du Colombier p9mode = OEXEC;
61086a363ceSDavid du Colombier break;
61186a363ceSDavid du Colombier default:
61286a363ceSDavid du Colombier p9mode = OREAD;
61386a363ceSDavid du Colombier break;
6148ccd4a63SDavid du Colombier }
61586a363ceSDavid du Colombier else
6168ccd4a63SDavid du Colombier if (desiredaccess & SMB_DA_SPECIFIC_READ_DATA)
6178ccd4a63SDavid du Colombier if (desiredaccess & (SMB_DA_SPECIFIC_WRITE_DATA | SMB_DA_SPECIFIC_APPEND_DATA))
6188ccd4a63SDavid du Colombier p9mode = ORDWR;
6198ccd4a63SDavid du Colombier else
6208ccd4a63SDavid du Colombier p9mode = OREAD;
6218ccd4a63SDavid du Colombier else if (desiredaccess & (SMB_DA_SPECIFIC_WRITE_DATA | SMB_DA_SPECIFIC_APPEND_DATA))
6228ccd4a63SDavid du Colombier p9mode = ORDWR;
6238ccd4a63SDavid du Colombier else
6248ccd4a63SDavid du Colombier p9mode = OREAD;
6258ccd4a63SDavid du Colombier
6268ccd4a63SDavid du Colombier if (shareaccess == SMB_SA_NO_SHARE)
6278ccd4a63SDavid du Colombier sharemode = SMB_OPEN_MODE_SHARE_EXCLUSIVE;
6288ccd4a63SDavid du Colombier else if (shareaccess & (SMB_SA_SHARE_READ | SMB_SA_SHARE_WRITE) ==
6298ccd4a63SDavid du Colombier (SMB_SA_SHARE_READ | SMB_SA_SHARE_WRITE))
6308ccd4a63SDavid du Colombier sharemode = SMB_OPEN_MODE_SHARE_DENY_NONE;
6318ccd4a63SDavid du Colombier else if (shareaccess & SMB_SA_SHARE_READ)
6328ccd4a63SDavid du Colombier sharemode = SMB_OPEN_MODE_SHARE_DENY_WRITE;
6338ccd4a63SDavid du Colombier else if (shareaccess & SMB_SA_SHARE_WRITE)
6348ccd4a63SDavid du Colombier sharemode = SMB_OPEN_MODE_SHARE_DENY_READOREXEC;
6358ccd4a63SDavid du Colombier else
6368ccd4a63SDavid du Colombier sharemode = SMB_OPEN_MODE_SHARE_DENY_NONE;
6378ccd4a63SDavid du Colombier
6388ccd4a63SDavid du Colombier mode = (sharemode << SMB_OPEN_MODE_SHARE_SHIFT) | (p9mode << SMB_OPEN_MODE_ACCESS_SHIFT);
6398ccd4a63SDavid du Colombier
6408ccd4a63SDavid du Colombier switch (createdisposition) {
6418ccd4a63SDavid du Colombier default:
6428ccd4a63SDavid du Colombier smblogprint(-1, "smbcomntcreateandx: createdisposition 0x%.8lux not implemented\n", createdisposition);
6438ccd4a63SDavid du Colombier goto unimp;
6448ccd4a63SDavid du Colombier case SMB_CD_OPEN:
6458ccd4a63SDavid du Colombier ofun = SMB_OFUN_EXIST_OPEN;
6468ccd4a63SDavid du Colombier break;
6478ccd4a63SDavid du Colombier case SMB_CD_CREATE:
6488ccd4a63SDavid du Colombier ofun = SMB_OFUN_EXIST_FAIL | SMB_OFUN_NOEXIST_CREATE;
6498ccd4a63SDavid du Colombier break;
6508ccd4a63SDavid du Colombier case SMB_CD_OPEN_IF:
6518ccd4a63SDavid du Colombier ofun = SMB_OFUN_EXIST_OPEN | SMB_OFUN_NOEXIST_CREATE;
6528ccd4a63SDavid du Colombier break;
6538ccd4a63SDavid du Colombier case SMB_CD_OVERWRITE:
6548ccd4a63SDavid du Colombier ofun = SMB_OFUN_EXIST_TRUNCATE;
6558ccd4a63SDavid du Colombier break;
6568ccd4a63SDavid du Colombier case SMB_CD_OVERWRITE_IF:
6578ccd4a63SDavid du Colombier ofun = SMB_OFUN_EXIST_TRUNCATE | SMB_OFUN_NOEXIST_CREATE;
6588ccd4a63SDavid du Colombier break;
6598ccd4a63SDavid du Colombier }
6608ccd4a63SDavid du Colombier
6618ccd4a63SDavid du Colombier t = smbidmapfind(s->tidmap, h->tid);
6628ccd4a63SDavid du Colombier if (t == nil) {
6638ccd4a63SDavid du Colombier smbseterror(s, ERRSRV, ERRinvtid);
6648ccd4a63SDavid du Colombier pr = SmbProcessResultError;
6658ccd4a63SDavid du Colombier goto done;
6668ccd4a63SDavid du Colombier }
6678ccd4a63SDavid du Colombier
6688ccd4a63SDavid du Colombier f = openfile(s, t, path, mode, extfileattributes, ofun, createoptions, allocationsize, &fid, &d, &action);
6698ccd4a63SDavid du Colombier
6708ccd4a63SDavid du Colombier if (f == nil) {
6718ccd4a63SDavid du Colombier pr = SmbProcessResultError;
6728ccd4a63SDavid du Colombier goto done;
6738ccd4a63SDavid du Colombier }
6748ccd4a63SDavid du Colombier
6758ccd4a63SDavid du Colombier h->wordcount = 42;
6768ccd4a63SDavid du Colombier mtime = smbplan9time2time(d->mtime);
6778ccd4a63SDavid du Colombier if (!smbbufferputandxheader(s->response, h, &s->peerinfo, andxcommand, &andxoffsetfixup)
6788ccd4a63SDavid du Colombier || !smbbufferputb(s->response, 0) // oplocks? pah
6798ccd4a63SDavid du Colombier || !smbbufferputs(s->response, fid)
6808ccd4a63SDavid du Colombier || !smbbufferputl(s->response, action)
6818ccd4a63SDavid du Colombier || !smbbufferputv(s->response, mtime)
6828ccd4a63SDavid du Colombier || !smbbufferputv(s->response, smbplan9time2time(d->atime))
6838ccd4a63SDavid du Colombier || !smbbufferputv(s->response, mtime)
6848ccd4a63SDavid du Colombier || !smbbufferputv(s->response, mtime)
6858ccd4a63SDavid du Colombier || !smbbufferputl(s->response, smbplan9mode2dosattr(d->mode))
6868ccd4a63SDavid du Colombier || !smbbufferputv(s->response, smbl2roundupvlong(d->length, smbglobals.l2allocationsize))
6878ccd4a63SDavid du Colombier || !smbbufferputv(s->response, d->length)
6888ccd4a63SDavid du Colombier || !smbbufferputbytes(s->response, nil, 4)
6898ccd4a63SDavid du Colombier || !smbbufferputb(s->response, (d->qid.type & QTDIR) != 0)
6908ccd4a63SDavid du Colombier || !smbbufferputbytes(s->response, nil, 8)
6918ccd4a63SDavid du Colombier || !smbbufferputs(s->response, 0)) {
6928ccd4a63SDavid du Colombier pr = SmbProcessResultMisc;
6938ccd4a63SDavid du Colombier goto done;
6948ccd4a63SDavid du Colombier }
6958ccd4a63SDavid du Colombier
6968ccd4a63SDavid du Colombier if (andxcommand != SMB_COM_NO_ANDX_COMMAND)
6978ccd4a63SDavid du Colombier pr = smbchaincommand(s, h, andxoffsetfixup, andxcommand, andxoffset, b);
6988ccd4a63SDavid du Colombier else
6998ccd4a63SDavid du Colombier pr = SmbProcessResultReply;
7008ccd4a63SDavid du Colombier
7018ccd4a63SDavid du Colombier goto done;
7028ccd4a63SDavid du Colombier
7038ccd4a63SDavid du Colombier unimp:
7048ccd4a63SDavid du Colombier pr = SmbProcessResultUnimp;
7058ccd4a63SDavid du Colombier
7068ccd4a63SDavid du Colombier done:
7078ccd4a63SDavid du Colombier free(path);
7088ccd4a63SDavid du Colombier free(d);
7098ccd4a63SDavid du Colombier
7108ccd4a63SDavid du Colombier return pr;
7118ccd4a63SDavid du Colombier }
7128ccd4a63SDavid du Colombier
713