ref: 8f5375fa61acb4da83e855e40402d12be01a8c68
parent: b15accceac5f79106bb6a115985eed63284171cf
author: cinap_lenrek <cinap_lenrek@centraldogma>
date: Mon Jan 16 13:42:16 EST 2012
cifs: updated cifs/smb client to quintiles latest version
--- a/sys/man/4/cifs
+++ b/sys/man/4/cifs
@@ -20,6 +20,9 @@
] [
.B -m
.I mntpnt
+] [
+.B -t
+.I dfs-timeout
]
.I host
[
@@ -32,8 +35,7 @@
(shares or trees in MS terminology) published by such servers.
.PP
The root of the mounted directory contains one subdirectory per share,
-always named in lower case, and a few virtual files of mixed case which
-give additional server, session, share, and user information.
+and a few virtual files give additional information.
The arguments are:
.TF "-a\fI auth-method"
.PD
@@ -71,6 +73,14 @@
.B -D
9P request debug.
.TP
+.B -i
+By default
+.I cifs(4)
+attempts to enforce case significance file and directory names, though objects
+which differ only in their case still cannot co-exist in the same directory. The
+.B -i
+option disables this behaveiour.
+.TP
.BI -k " keyparam"
lists extra parameters which will be passed to
.IR factotum (4)
@@ -112,6 +122,11 @@
post the service as
.BI /srv/ srvname.
.TP
+.BI -t " dfs-timeout"
+sets the timeout in for DFS redirections - it defaults to 100ms.
+This is a reasonable minimum, it should have a value just greater than
+the RTT to the most distant server being accessed.
+.TP
.I host
The address of the remote server to connect to.
.TP
@@ -126,7 +141,7 @@
.TP
.B Shares
Contains a list of the currently attached shares,
-with fields giving the share name, disk free space / capacity, the share type,
+with fields giving the share name, the share type, disk free space / capacity,
and a descriptive comment from the server.
.TP
.B Connection
@@ -161,27 +176,48 @@
giving the features of that OS.
.TP
.B Dfsroot
-Top level DFS routing giving the DFS link type, time to live of the data,
-proximity of the server, the Netbios or DNS name and
-a physical path or a machine that this maps to.
-.IP
-DNS paths are usually assigned dynamicially as a form of load balancing.
+Lists the top level DFS domains and the servers that
+provision them.
+.TP
+.B Dfscache
+Contents of the DFS referal cache, giving the path prefix,
+the expiry time (or -1 for never), the measured RTT to the server
+in milliseconds, the server proximity (0 is local), the server name,
+and the share name on that server.
+.SH COMPATIBILITY
+.I Cifs
+has been tested against
+.IR aquarela (8),
+Windows 95, NT4.0sp6,
+Windows server 2003, Windows server 2003, WinXP pro,
+Samba 2.0 (Pluto VideoSpace), and Samba 3.0.
+.LP
+Windows Vista require a hotfix (registry change)
+to support NTLMv2 without GSSAPI, see http://support.microsoft.com/kb/957441.
+Alternatively the
+.B -a
+option can be used to force
+.I cifs
+to use one of the less secure authentication mechnisms.
+.LP
+Windows 7 has dropped support for RAP, which is used to generate
+the synthetic files offered by
+.IR cifs .
+RAP is also used to enumerate the shares offered by the remote host so
+remote share names must always be specified on the command line.
+.LP
+The NetApp Filer was supported by earlier releases, however recent
+attempts to mount one have failed. Should a server be available it is
+likely that this could be easily fixed.
+.PP
.SH SOURCE
.B /sys/src/cmd/cifs
.SH SEE ALSO
.IR factotum (4),
-.IR cifsd (8)
+.IR aquarela (8)
.SH BUGS
-NetApp Filer compatibility has not yet been tested; there may not be any.
+DFS support is unfinished, it will not follow referals that span servers.
.PP
-DFS support is unfinished.
+Kerberos authentication is not supported.
.PP
-Kerberos authentication is unfinished.
-.PP
NetBios name resolution is not supported, though it is now rarely used.
-.PP
-.I Cifs
-has only been tested against
-aquarela, Windows 95, NT4.0sp6,
-Windows server 2003, WinXP pro, Samba 3.0, and Samba 2.0 (Pluto VideoSpace).
-No support is attempted for servers predating NT 4.0.
--- a/sys/src/cmd/cifs/auth-testcase.c
+++ b/sys/src/cmd/cifs/auth-testcase.c
@@ -137,31 +137,29 @@
static int
ntv2_blob(uchar *blob, int len, char *windom)
{
- int n;
- uvlong nttime;
- Rune r;
- char *d;
+ uvlong t;
uchar *p;
enum { /* name types */
Beof, /* end of name list */
- Bnetbios, /* Netbios machine name */
+ Bhost, /* Netbios host name */
Bdomain, /* Windows Domain name (NT) */
- Bdnsfqdn, /* DNS Fully Qualified Domain Name */
- Bdnsname, /* DNS machine name (win2k) */
+ Bdnshost, /* DNS host name */
+ Bdnsdomain, /* DNS domain name */
};
p = blob;
- *p++ = 1; /* response type */
- *p++ = 1; /* max response type understood by client */
+ *p++ = 1; /* 8bit: response type */
+ *p++ = 1; /* 8bit: max response type understood by client */
+ *p++ = 0; /* 16bit: reserved */
*p++ = 0;
- *p++ = 0; /* 2 bytes reserved */
+ *p++ = 0; /* 32bit: unknown */
*p++ = 0;
*p++ = 0;
*p++ = 0;
- *p++ = 0; /* 4 bytes unknown */
+
#ifdef NTLMV2_TEST
*p++ = 0xf0;
*p++ = 0x20;
@@ -172,18 +170,19 @@
*p++ = 0xbe;
*p++ = 0x01;
#else
- nttime = time(nil); /* nt time now */
- nttime = nttime + 11644473600LL;
- nttime = nttime * 10000000LL;
- *p++ = nttime & 0xff;
- *p++ = (nttime >> 8) & 0xff;
- *p++ = (nttime >> 16) & 0xff;
- *p++ = (nttime >> 24) & 0xff;
- *p++ = (nttime >> 32) & 0xff;
- *p++ = (nttime >> 40) & 0xff;
- *p++ = (nttime >> 48) & 0xff;
- *p++ = (nttime >> 56) & 0xff;
+ t = time(nil); /* 64bit: time in NT format */
+ t += 11644473600LL;
+ t *= 10000000LL;
+ *p++ = t;
+ *p++ = t >> 8;
+ *p++ = t >> 16;
+ *p++ = t >> 24;
+ *p++ = t >> 32;
+ *p++ = t >> 40;
+ *p++ = t >> 48;
+ *p++ = t >> 56;
#endif
+
#ifdef NTLMV2_TEST
*p++ = 0x05;
*p++ = 0x83;
@@ -195,38 +194,17 @@
*p++ = 0x6d;
#else
genrandom(p, 8);
- p += 8; /* client nonce */
+ p += 8; /* 64bit: client nonce */
#endif
- *p++ = 0x6f;
- *p++ = 0;
- *p++ = 0x6e;
- *p++ = 0; /* unknown data */
- *p++ = Bdomain;
- *p++ = 0; /* name type */
-
- n = utflen(windom) * 2;
- *p++ = n;
- *p++ = n >> 8; /* name length */
-
- d = windom;
- while(*d && p - blob < len - 8){
- d += chartorune(&r, d);
- r = toupperrune(r);
- *p++ = r;
- *p++ = r >> 8;
- }
-
+ *p++ = 0; /* 32bit: unknown data */
*p++ = 0;
- *p++ = Beof; /* name type */
-
*p++ = 0;
- *p++ = 0; /* name length */
-
- *p++ = 0x65;
*p++ = 0;
- *p++ = 0;
- *p++ = 0; /* unknown data */
+
+ p += putname(p, len - (p-blob), windom, Bdomain);
+ p += putname(p, len - (p-blob), "", Beof);
+
return p - blob;
}
--- a/sys/src/cmd/cifs/auth.c
+++ b/sys/src/cmd/cifs/auth.c
@@ -135,77 +135,80 @@
static int
-ntv2_blob(uchar *blob, int len, char *windom)
+putname(uchar *buf, int len, char *name, int type)
{
int n;
- uvlong nttime;
Rune r;
char *d;
+ uchar *p = buf;
+
+ *p++ = type;
+ *p++ = 0; /* 16bit: name type */
+
+ n = utflen(name) * 2;
+ *p++ = n;
+ *p++ = n >> 8; /* 16bit: name length */
+
+ d = name;
+ while(*d != 0 && p-buf < len-8){
+ d += chartorune(&r, d);
+ r = toupperrune(r);
+ *p++ = r;
+ *p++ = r >> 8;
+ } /* var: actual name */
+
+ return p - buf;
+}
+
+static int
+ntv2_blob(uchar *blob, int len, char *windom)
+{
+ uvlong t;
uchar *p;
enum { /* name types */
Beof, /* end of name list */
- Bnetbios, /* Netbios machine name */
+ Bhost, /* Netbios host name */
Bdomain, /* Windows Domain name (NT) */
- Bdnsfqdn, /* DNS Fully Qualified Domain Name */
- Bdnsname, /* DNS machine name (win2k) */
+ Bdnshost, /* DNS host name */
+ Bdnsdomain, /* DNS domain name */
};
p = blob;
- *p++ = 1; /* response type */
- *p++ = 1; /* max response type understood by client */
+ *p++ = 1; /* 8bit: response type */
+ *p++ = 1; /* 8bit: max response type understood by client */
+ *p++ = 0; /* 16bit: reserved */
*p++ = 0;
- *p++ = 0; /* 2 bytes reserved */
+ *p++ = 0; /* 32bit: unknown */
*p++ = 0;
*p++ = 0;
*p++ = 0;
- *p++ = 0; /* 4 bytes unknown */
- nttime = time(nil); /* nt time now */
- nttime += 11644473600LL;
- nttime *= 10000000LL;
- *p++ = nttime;
- *p++ = nttime >> 8;
- *p++ = nttime >> 16;
- *p++ = nttime >> 24;
- *p++ = nttime >> 32;
- *p++ = nttime >> 40;
- *p++ = nttime >> 48;
- *p++ = nttime >> 56;
+ t = time(nil);
+ t += 11644473600LL;
+ t *= 10000000LL;
+ *p++ = t; /* 64bit: time in NT format */
+ *p++ = t >> 8;
+ *p++ = t >> 16;
+ *p++ = t >> 24;
+ *p++ = t >> 32;
+ *p++ = t >> 40;
+ *p++ = t >> 48;
+ *p++ = t >> 56;
+
genrandom(p, 8);
- p += 8; /* client nonce */
- *p++ = 0x6f;
- *p++ = 0;
- *p++ = 0x6e;
- *p++ = 0; /* unknown data */
+ p += 8; /* 64bit: client nonce */
- *p++ = Bdomain;
- *p++ = 0; /* name type */
-
- n = utflen(windom) * 2;
- *p++ = n;
- *p++ = n >> 8; /* name length */
-
- d = windom;
- while(*d && p-blob < (len-8)){
- d += chartorune(&r, d);
- r = toupperrune(r);
- *p++ = r;
- *p++ = r >> 8;
- }
-
+ *p++ = 0; /* 32bit: unknown data */
*p++ = 0;
- *p++ = Beof; /* name type */
-
*p++ = 0;
- *p++ = 0; /* name length */
-
- *p++ = 0x65;
*p++ = 0;
- *p++ = 0;
- *p++ = 0; /* unknown data */
+
+ p += putname(p, len - (p-blob), windom, Bdomain);
+ p += putname(p, len - (p-blob), "", Beof);
+
return p - blob;
}
@@ -293,7 +296,7 @@
memcpy(ap->mackey[0]+MD5dlen, ap->resp[0], MACkeylen-MD5dlen);
/* NTLM v2 */
- n = ntv2_blob(blob, sizeof(blob), windom);
+ n = ntv2_blob(blob, sizeof blob, windom);
ds = hmac_t64(chal, len, v2hash, MD5dlen, nil, nil);
hmac_t64(blob, n, v2hash, MD5dlen, nt_hmac, ds);
ap->len[1] = MD5dlen+n;
--- a/sys/src/cmd/cifs/cifs.c
+++ b/sys/src/cmd/cifs/cifs.c
@@ -40,8 +40,12 @@
s->seqrun = 0;
s->secmode = SECMODE_SIGN_ENABLED; /* hope for the best */
s->flags2 = FL2_KNOWS_LONG_NAMES | FL2_HAS_LONG_NAMES | FL2_PAGEING_IO;
+
s->macidx = -1;
+ if(s->mtu > MTU)
+ s->mtu = MTU;
+
return s;
}
@@ -76,6 +80,7 @@
p->buf = (uchar *)p + sizeof(Pkt);
p->s = s;
+ p->request = cmd; /* for debug */
qlock(&s->seqlock);
if(s->seqrun){
@@ -137,11 +142,12 @@
int
cifsrpc(Pkt *p)
{
- int flags2, got, err;
+ int reply, got, err;
uint tid, uid, seq;
uchar *pos;
char m[nelem(magic)];
+
pos = p->pos;
if(p->bytebase){
p->pos = p->bytebase;
@@ -155,20 +161,23 @@
qlock(&p->s->rpclock);
got = nbtrpc(p);
qunlock(&p->s->rpclock);
- if(got == -1)
+
+ if(got < 32+NBHDRLEN){
+ werrstr("cifs packet too small (%d < %d)\n", got, 32+NBHDRLEN);
return -1;
+ }
gmem(p, m, nelem(magic));
if(memcmp(m, magic, nelem(magic)) != 0){
- werrstr("cifsrpc: bad magic number in packet %20ux%02ux%02ux%02ux",
+ werrstr("cifsrpc: bad magic number in packet 0x%02ux%02ux%02ux%02ux",
m[0], m[1], m[2], m[3]);
return -1;
}
- g8(p); /* cmd */
+ reply = g8(p); /* cmd */
err = gl32(p); /* errcode */
g8(p); /* flags */
- flags2 = gl16(p); /* flags2 */
+ p->flags2 = gl16(p); /* flags2 */
gl16(p); /* PID MS bits */
seq = gl32(p); /* reserved */
gl32(p); /* MAC (if in use) */
@@ -179,6 +188,12 @@
gl16(p); /* mid */
g8(p); /* word count */
+ if(reply != p->request){
+ fprint(2, "unexpected reply (cmd=%x/%x seq=%d/%d)\n",
+ reply, p->request, seq, p->seq);
+ return -1;
+ }
+
if(p->s->secmode & SECMODE_SIGN_ENABLED){
if(macsign(p, p->seq+1) != 0 && p->s->seqrun){
werrstr("cifsrpc: invalid packet signature");
@@ -196,7 +211,7 @@
* catch that too.
*/
if(p->s->seqrun && seq != p->seq && seq != 0){
- print("%ux != %ux bad sequence number\n", seq, p->seq);
+ werrstr("bad sequence number (%d != %d)\n", p->seq, seq);
return -1;
}
}
@@ -205,7 +220,7 @@
if(p->s->uid == NO_UID)
p->s->uid = uid;
- if(flags2 & FL2_NT_ERRCODES){
+ if(p->flags2 & FL2_NT_ERRCODES){
/* is it a real error rather than info/warning/chatter? */
if((err & 0xF0000000) == 0xC0000000){
werrstr("%s", nterrstr(err));
@@ -243,11 +258,26 @@
};
Pkt *p;
+ /*
+ * This should not be necessary, however the XP seems to use
+ * Unicode strings in its Negoiate response, but not set the
+ * Flags2 UNICODE flag.
+ *
+ * It does however echo back the FL_UNICODE flag we set in the
+ * flags2 negoiate request.
+ *
+ * The bodge is to force FL_UNICODE for this single request,
+ * clearing it after. Later we set FL2_UNICODE if the server
+ * agrees to CAP_UNICODE as it "should" be done.
+ */
+ s->flags2 |= FL2_UNICODE;
p = cifshdr(s, nil, SMB_COM_NEGOTIATE);
+ s->flags2 &= ~FL2_UNICODE;
+
pbytes(p);
for(i = 0; i < nelem(dialects); i++){
p8(p, STR_DIALECT);
- pstr(p, dialects[i]);
+ pascii(p, dialects[i]);
}
if(cifsrpc(p) == -1){
@@ -277,7 +307,7 @@
gl32(p); /* Session key */
s->caps = gl32(p); /* Server capabilities */
*svrtime = gvtime(p); /* fileserver time */
- s->tz = (short)gl16(p) * 60; /* TZ in mins, is signed (SNIA doc is wrong) */
+ s->tz = (short)gl16(p) * 60; /* TZ in mins, is signed (SNIA doc is wrong) */
s->challen = g8(p); /* Encryption key length */
gl16(p);
gmem(p, s->chal, s->challen); /* Get the challenge */
@@ -368,7 +398,7 @@
gl16(p);
gl16(p);
/* no security blob here - we don't understand extended security anyway */
- gstr(p, os, sizeof(os));
+ gstr(p, os, sizeof os);
s->remos = estrdup9p(os);
free(p);
@@ -386,9 +416,9 @@
resp = Sess->auth->resp[0];
len = Sess->auth->len[0];
if((s->secmode & SECMODE_USER) != SECMODE_USER){
- memset(zeros, 0, sizeof(zeros));
+ memset(zeros, 0, sizeof zeros);
resp = zeros;
- len = sizeof(zeros);
+ len = sizeof zeros;
}
p = cifshdr(s, nil, SMB_COM_TREE_CONNECT_ANDX);
@@ -408,11 +438,11 @@
}
path = smprint("//%s/%s", cname, tree);
- strupr(path);
+
ppath(p, path); /* path */
free(path);
- pascii(p, "?????"); /* service type any (so we can do RAP calls) */
+ pascii(p, "?????"); /* service type any (so we can do RAP calls) */
if(cifsrpc(p) == -1){
free(p);
--- a/sys/src/cmd/cifs/cifs.h
+++ b/sys/src/cmd/cifs/cifs.h
@@ -350,10 +350,10 @@
int uid; /* user (authentication) ID */
int seq; /* sequence number */
int seqrun; /* sequence numbering active */
- int caps; /* server capabilities */
+ int caps; /* server's capabilities */
int support; /* support bits */
- int flags; /* SMB flags */
- int flags2; /* SMB flags 2 */
+ int flags; /* SMB flags that we will send in the next packet */
+ int flags2; /* SMB flags 2 that we will send in the next packet */
int nocache; /* disable write behind caching in server */
int pid; /* process ID */
int mid; /* multiplex ID */
@@ -378,6 +378,8 @@
int tid; /* tree ID received from server */
int seq; /* sequence number expected in reply */
+ int request; /* request cmd no (for debug) */
+ int flags2; /* flags2 received with this packet */
uchar *seqbase; /* cifs: pos of sequence number in packet */
uchar *wordbase; /* cifs: base of words section of data */
@@ -483,156 +485,150 @@
extern Share Shares[MAX_SHARES];
extern int Nshares;
-/* main.c */
-Qid mkqid(char *, int, long, int, long);
-
/* auth.c */
-Auth *getauth(char *, char *, char *, int, uchar *, int);
-void autherr(void);
-int macsign(Pkt *, int);
+extern void autherr(void);
+extern Auth *getauth(char *name, char *windom, char *keyp, int secmode, uchar *chal, int len);
+extern int macsign(Pkt *p, int seq);
/* cifs.c */
-Session *cifsdial(char *, char *, char *);
-void cifsclose(Session *);
-Pkt *cifshdr(Session *, Share *, int);
-void pbytes(Pkt *);
-int cifsrpc(Pkt *);
-int CIFSnegotiate(Session *, long *, char *, int, char *, int);
-int CIFSsession(Session *);
-int CIFStreeconnect(Session *, char *, char *, Share *);
-int CIFSlogoff(Session *);
-int CIFStreedisconnect(Session *, Share *);
-int CIFSdeletefile(Session *, Share *, char *);
-int CIFSdeletedirectory(Session *, Share *, char *);
-int CIFScreatedirectory(Session *, Share *, char *);
-int CIFSrename(Session *, Share *, char *, char *);
-int CIFS_NT_opencreate(Session *, Share *, char *, int, int, int, int, int, int, int *, FInfo *);
-int CIFS_SMB_opencreate(Session *, Share *, char *, int, int, int, int *);
-vlong CIFSwrite(Session *, Share *, int, uvlong, void *, vlong);
-vlong CIFSread(Session *, Share *, int, uvlong, void *, vlong, vlong);
-int CIFSflush(Session *, Share *, int);
-int CIFSclose(Session *, Share *, int);
-int CIFSfindclose2(Session *, Share *, int);
-int CIFSecho(Session *);
-int CIFSsetinfo(Session *, Share *, char *, FInfo *);
-void goff(Pkt *, uchar *, char *, int);
+extern Session *cifsdial(char *host, char *called, char *sysname);
+extern void cifsclose(Session *s);
+extern Pkt *cifshdr(Session *s, Share *sp, int cmd);
+extern void pbytes(Pkt *p);
+extern int cifsrpc(Pkt *p);
+extern int CIFSnegotiate(Session *s, long *svrtime, char *domain, int domlen, char *cname, int cnamlen);
+extern int CIFSsession(Session *s);
+extern int CIFStreeconnect(Session *s, char *cname, char *tree, Share *sp);
+extern int CIFSlogoff(Session *s);
+extern int CIFStreedisconnect(Session *s, Share *sp);
+extern int CIFSdeletefile(Session *s, Share *sp, char *name);
+extern int CIFSdeletedirectory(Session *s, Share *sp, char *name);
+extern int CIFScreatedirectory(Session *s, Share *sp, char *name);
+extern int CIFSrename(Session *s, Share *sp, char *old, char *new);
+extern int CIFS_NT_opencreate(Session *s, Share *sp, char *name, int flags, int options, int attrs, int access, int share, int action, int *result, FInfo *fi);
+extern int CIFS_SMB_opencreate(Session *s, Share *sp, char *name, int access, int attrs, int action, int *result);
+extern vlong CIFSwrite(Session *s, Share *sp, int fh, uvlong off, void *buf, vlong n);
+extern vlong CIFSread(Session *s, Share *sp, int fh, uvlong off, void *buf, vlong n, vlong minlen);
+extern int CIFSflush(Session *s, Share *sp, int fh);
+extern int CIFSclose(Session *s, Share *sp, int fh);
+extern int CIFSfindclose2(Session *s, Share *sp, int sh);
+extern int CIFSecho(Session *s);
+extern int CIFSsetinfo(Session *s, Share *sp, char *path, FInfo *fip);
/* dfs.c */
-char *mapfile(char *);
-int mapshare(char *, Share **);
-int redirect(Session *, Share *s, char *);
-int dfscacheinfo(Fmt *);
-char *trimshare(char *);
+extern int dfscacheinfo(Fmt *f);
+extern char *trimshare(char *s);
+extern char *mapfile(char *opath);
+extern int mapshare(char *path, Share **osp);
+extern int redirect(Session *s, Share *sp, char *path);
/* doserrstr.c */
-char *doserrstr(uint);
+extern char *doserrstr(uint err);
/* fs.c */
-int shareinfo(Fmt *);
-int conninfo(Fmt *);
-int sessioninfo(Fmt *);
-int userinfo(Fmt *);
-int groupinfo(Fmt *);
-int domaininfo(Fmt *);
-int workstationinfo(Fmt *);
-int dfsrootinfo(Fmt *);
-int openfileinfo(Fmt *);
-int dfsrootinfo(Fmt *);
-int filetableinfo(Fmt *); /* is in main.c due to C scope */
+extern int shareinfo(Fmt *f);
+extern int openfileinfo(Fmt *f);
+extern int conninfo(Fmt *f);
+extern int sessioninfo(Fmt *f);
+extern int dfsrootinfo(Fmt *f);
+extern int userinfo(Fmt *f);
+extern int groupinfo(Fmt *f);
+extern int domaininfo(Fmt *f);
+extern int workstationinfo(Fmt *f);
/* info.c */
-int walkinfo(char *);
-int numinfo(void);
-int dirgeninfo(int, Dir *);
-int makeinfo(int);
-int readinfo(int, char *, int, int);
-void freeinfo(int);
+extern int walkinfo(char *name);
+extern int numinfo(void);
+extern int dirgeninfo(int slot, Dir *d);
+extern int makeinfo(int path);
+extern int readinfo(int path, char *buf, int len, int off);
+extern void freeinfo(int path);
/* main.c */
-void usage(void);
-void dmpkey(char *, void *, int);
-void main(int, char **);
+extern void setup(void);
+extern int filetableinfo(Fmt *f);
+extern Qid mkqid(char *s, int is_dir, long vers, int subtype, long path);
+extern int rdonly(Session *s, Share *sp, char *path, int rdonly);
+extern void usage(void);
+extern void dmpkey(char *s, void *v, int n);
+extern void main(int argc, char **argv);
/* misc.c */
-char *strupr(char *);
-char *strlwr(char *);
+extern char *strupr(char *s);
+extern char *strlwr(char *s);
/* netbios.c */
-void Gmem(uchar **, void *, int);
-int calledname(char *, char *);
-int nbtdial(char *, char *, char *);
-void nbthdr(Pkt *);
-int nbtrpc(Pkt *);
-void xd(char *, void *, int);
+extern void Gmem(uchar **p, void *v, int n);
+extern int calledname(char *host, char *name);
+extern int nbtdial(char *addr, char *called, char *sysname);
+extern void nbthdr(Pkt *p);
+extern int nbtrpc(Pkt *p);
+extern void xd(char *str, void *buf, int n);
/* nterrstr.c */
-char *nterrstr(uint);
+extern char *nterrstr(uint err);
/* pack.c */
-void *pmem(Pkt *, void *, int);
-void *ppath(Pkt *, char *);
-void *pstr(Pkt *, char *);
-void *pascii(Pkt *, char *);
-void *pl64(Pkt *, uvlong);
-void *pb32(Pkt *, uint);
-void *pl32(Pkt *, uint);
-void *pb16(Pkt *, uint);
-void *pl16(Pkt *, uint);
-void *p8(Pkt *, uint);
-void *pname(Pkt *, char *, char);
-void *pvtime(Pkt *, uvlong);
-void *pdatetime(Pkt *, long);
-void gmem(Pkt *, void *, int);
-void gstr(Pkt *, char *, int);
-void gascii(Pkt *, char *, int);
-uvlong gl64(Pkt *);
-uvlong gb48(Pkt *);
-uint gb32(Pkt *);
-uint gl32(Pkt *);
-uint gb16(Pkt *);
-uint gl16(Pkt *);
-uint g8(Pkt *);
-long gdatetime(Pkt *);
-long gvtime(Pkt *);
-void gconv(Pkt *, int, char *, int);
+extern void *pmem(Pkt *p, void *v, int len);
+extern void *ppath(Pkt *p, char *str);
+extern void *pstr(Pkt *p, char *str);
+extern void *pascii(Pkt *p, char *str);
+extern void *pl64(Pkt *p, uvlong n);
+extern void *pb32(Pkt *p, uint n);
+extern void *pl32(Pkt *p, uint n);
+extern void *pb16(Pkt *p, uint n);
+extern void *pl16(Pkt *p, uint n);
+extern void *p8(Pkt *p, uint n);
+extern void *pname(Pkt *p, char *name, char pad);
+extern void *pvtime(Pkt *p, uvlong n);
+extern void *pdatetime(Pkt *p, long utc);
+extern void gmem(Pkt *p, void *v, int n);
+extern void gstr(Pkt *p, char *str, int n);
+extern void gascii(Pkt *p, char *str, int n);
+extern uvlong gl64(Pkt *p);
+extern uvlong gb48(Pkt *p);
+extern uint gb32(Pkt *p);
+extern uint gl32(Pkt *p);
+extern uint gb16(Pkt *p);
+extern uint gl16(Pkt *p);
+extern uint g8(Pkt *p);
+extern long gdatetime(Pkt *p);
+extern long gvtime(Pkt *p);
+extern void gconv(Pkt *p, int conv, char *str, int n);
+extern void goff(Pkt *p, uchar *base, char *str, int n);
+/* ping.c */
+extern int ping(char *host, int timeout);
+
/* raperrstr.c */
-char *raperrstr(uint);
+extern char *raperrstr(uint err);
/* sid2name.c */
-void upd_names(Session *, Share *, char *, Dir *);
+extern void upd_names(Session *s, Share *sp, char *path, Dir *d);
/* trans.c */
-int RAPshareenum(Session *, Share *, Share **);
-int RAPshareinfo(Session *, Share *, char *, Shareinfo2 *);
+extern int RAPshareenum(Session *s, Share *sp, Share **ent);
+extern int RAPshareinfo(Session *s, Share *sp, char *share, Shareinfo2 *si2p);
+extern int RAPsessionenum(Session *s, Share *sp, Sessinfo **sip);
+extern int RAPgroupenum(Session *s, Share *sp, Namelist **nlp);
+extern int RAPgroupusers(Session *s, Share *sp, char *group, Namelist **nlp);
+extern int RAPuserenum(Session *s, Share *sp, Namelist **nlp);
+extern int RAPuserenum2(Session *s, Share *sp, Namelist **nlp);
+extern int RAPuserinfo(Session *s, Share *sp, char *user, Userinfo *uip);
+extern int RAPServerenum2(Session *s, Share *sp, char *workgroup, int type, int *more, Serverinfo **si);
+extern int RAPServerenum3(Session *s, Share *sp, char *workgroup, int type, int last, Serverinfo *si);
+extern int RAPFileenum2(Session *s, Share *sp, char *user, char *path, Fileinfo **fip);
-int RAPsessionenum(Session *, Share *, Sessinfo **);
-
-int RAPgroupenum(Session *, Share *, Namelist **);
-int RAPgroupusers(Session *, Share *, char *, Namelist **);
-
-int RAPuserenum(Session *, Share *, Namelist **);
-int RAPuserenum2(Session *, Share *, Namelist **);
-int RAPuserinfo(Session *, Share *, char *, Userinfo *);
-
-int RAPServerenum2(Session *, Share *, char *, int, int *, Serverinfo **);
-int RAPServerenum3(Session *, Share *, char *, int, int, Serverinfo *);
-
-int RAPFileenum2(Session *, Share *, char *, char *, Fileinfo **);
-
/* trans2.c */
-int T2findfirst(Session *, Share *, int, char *, int *, long *, FInfo *);
-int T2findnext(Session *, Share *, int, char *, int *, long *, FInfo *, int);
-int T2queryall(Session *, Share *, char *, FInfo *);
-int T2querystandard(Session *, Share *, char *, FInfo *);
-int T2setpathinfo(Session *, Share *, char *, FInfo *);
-int T2setfilelength(Session *, Share *, int, FInfo *);
-int T2fsvolumeinfo(Session *, Share *, long *, long *, char *, int);
-int T2fssizeinfo(Session *, Share *, uvlong *, uvlong *);
-int T2getdfsreferral(Session *, Share *, char *, int *, int *, Refer *, int);
+extern int T2findfirst(Session *s, Share *sp, int slots, char *path, int *got, long *resume, FInfo *fip);
+extern int T2findnext(Session *s, Share *sp, int slots, char *path, int *got, long *resume, FInfo *fip, int sh);
+extern int T2queryall(Session *s, Share *sp, char *path, FInfo *fip);
+extern int T2querystandard(Session *s, Share *sp, char *path, FInfo *fip);
+extern int T2setpathinfo(Session *s, Share *sp, char *path, FInfo *fip);
+extern int T2setfilelength(Session *s, Share *sp, int fh, FInfo *fip);
+extern int T2fsvolumeinfo(Session *s, Share *sp, long *created, long *serialno, char *label, int labellen);
+extern int T2fssizeinfo(Session *s, Share *sp, uvlong *total, uvlong *unused);
+extern int T2getdfsreferral(Session *s, Share *sp, char *path, int *gflags, int *used, Refer *re, int nent);
/* transnt.c */
-int TNTquerysecurity(Session *, Share *, int, char **, char **);
-
-/* ping.c */
-int ping(char *, int);
+extern int TNTquerysecurity(Session *s, Share *sp, int fh, char **usid, char **gsid);
--- a/sys/src/cmd/cifs/info.c
+++ b/sys/src/cmd/cifs/info.c
@@ -8,22 +8,22 @@
struct {
- char *name;
- int (*func)(Fmt *f);
- char *buf;
- int len;
+ char *name;
+ int (*func)(Fmt *f);
+ char *buf;
+ int len;
} Infdir[] = {
- { "Users", userinfo },
- { "Groups", groupinfo },
- { "Shares", shareinfo },
- { "Connection", conninfo },
- { "Sessions", sessioninfo },
- { "Dfsroot", dfsrootinfo },
- { "Dfscache", dfscacheinfo },
- { "Domains", domaininfo },
- { "Openfiles", openfileinfo },
- { "Workstations", workstationinfo },
- { "Filetable", filetableinfo },
+ { "Users" , userinfo },
+ { "Groups" , groupinfo },
+ { "Shares" , shareinfo },
+ { "Connection" , conninfo },
+ { "Sessions" , sessioninfo },
+ { "Dfsroot" , dfsrootinfo },
+ { "Dfscache" , dfscacheinfo },
+ { "Domains" , domaininfo },
+ { "Openfiles" , openfileinfo },
+ { "Workstations" , workstationinfo },
+ { "Filetable" , filetableinfo },
};
int
@@ -63,6 +63,7 @@
d->qid.vers = 1;
d->qid.path = slot;
d->qid.type = 0;
+
return 0;
}
@@ -76,10 +77,12 @@
if(Infdir[path].buf != nil)
return 0;
fmtstrinit(&f);
- if((*Infdir[path].func)(&f) == -1l)
+ if((*Infdir[path].func)(&f) == -1)
return -1;
- Infdir[path].buf = fmtstrflush(&f);
- Infdir[path].len = strlen(Infdir[path].buf);
+ if((Infdir[path].buf = fmtstrflush(&f)) == nil)
+ return -1;
+ if((Infdir[path].len = strlen(Infdir[path].buf)) <= 0)
+ return -1;
return 0;
}
@@ -104,3 +107,4 @@
free(Infdir[path].buf);
Infdir[path].buf = nil;
}
+
--- a/sys/src/cmd/cifs/main.c
+++ b/sys/src/cmd/cifs/main.c
@@ -198,8 +198,10 @@
Aux *a = aux;
char *npath;
int numinf = numinfo();
- int slots = min(Sess->mtu, MTU) / sizeof(FInfo);
+ int slots;
+ slots = 128; /* number of dir entries to fetch at one time */
+
if(strcmp(a->path, "/") == 0){
if(slot < numinf){
dirgeninfo(slot, d);
@@ -1103,6 +1105,7 @@
sleep(6000);
if(Active-- != 0)
continue;
+
for(i = 0; i < Nshares; i++){
if((rc = T2fssizeinfo(Sess, &Shares[slot], &tot, &fre)) == 0)
break;
@@ -1253,6 +1256,8 @@
memcpy(Shares+Nshares, sip+i, sizeof(Share));
if(CIFStreeconnect(Sess, Sess->cname,
Shares[Nshares].name, Shares+Nshares) == -1){
+ fprint(2, "%s: %s %q - can't connect to share"
+ ", %r\n", argv0, Host, Shares[Nshares].name);
free(Shares[Nshares].name);
continue;
}
@@ -1263,7 +1268,7 @@
for(i = 1; i < argc; i++){
if(CIFStreeconnect(Sess, Sess->cname, argv[i],
Shares+Nshares) == -1){
- fprint(2, "%s: %s %q - can't connect to share"
+ fprint(2, "%s: %s %q - can't connect to share"
", %r\n", argv0, Host, argv[i]);
continue;
}
--- a/sys/src/cmd/cifs/mkfile
+++ b/sys/src/cmd/cifs/mkfile
@@ -11,10 +11,3 @@
auth.$O dfs.$O ping.$O
</sys/src/cmd/mkone
-
-install:V:
- # cp $TARG.man /sys/man/4/$TARG
-
-
-test:V: 8.out
- 8.out se-00 root && ls /n/se-00/root/eng/design/conversion/* && p /n/se-00/Shares
--- a/sys/src/cmd/cifs/nterrstr.c
+++ b/sys/src/cmd/cifs/nterrstr.c
@@ -3,14 +3,14 @@
/*
* some lines commented 4APE have been changed to
- * make them the same as plan9 error messages. This is not
+ * make them the same as plan9 error messages. This is not
* a problem for native programs but those built on APE
* will give unhelpful errors if this is not done
- */
+*/
static struct {
- char *msg;
- int err;
+ char *msg;
+ int err;
} NTerrs[] = {
{ "success", 0x0 },
{ "wait 1", 0x1 },
@@ -261,8 +261,8 @@
{ "password restriction", 0xc000006c },
{ "logon failure", 0xc000006d },
{ "account restriction", 0xc000006e },
- { "invalid logon hours", 0xc000006f },
- { "invalid workstation", 0xc0000070 },
+ { "login disallowed at this time", 0xc000006f },
+ { "login disallowed from this workstation", 0xc0000070 },
{ "password expired", 0xc0000071 },
{ "account disabled", 0xc0000072 },
{ "none mapped", 0xc0000073 },
@@ -959,7 +959,7 @@
{ "SXS multiple deactivation", 0xc0150011 },
{ "SXS system default activation context empty",0xc0150012 },
{ "SXS process termination requested", 0xc0150013 },
-};
+ };
char *
nterrstr(uint err)
@@ -1006,14 +1006,13 @@
match = i;
why = "";
- if(!(err & 0x80000000))
+ if(! (err & 0x80000000))
why = "warning, ";
if(match != -1)
- snprint(buf, sizeof buf, "%s%s%s", why, facility,
- NTerrs[match].msg);
+ snprint(buf, sizeof(buf), "%s%s%s", why, facility, NTerrs[match].msg);
else
- snprint(buf, sizeof buf, "%s%s%d/0x%ux - unknown NT error",
- why, facility, err, err);
+ snprint(buf, sizeof(buf), "%s%s%d/0x%ux - unknown NT error", why, facility, err, err);
return buf;
}
+
--- a/sys/src/cmd/cifs/pack.c
+++ b/sys/src/cmd/cifs/pack.c
@@ -27,7 +27,7 @@
if(!str)
return s;
- if(p->s->caps & CAP_UNICODE){
+ if(p->s->flags2 & FL2_UNICODE){
if(((p->pos - p->buf) % 2) != 0) /* pad to even offset */
p8(p, 0);
while(*str){
@@ -57,7 +57,7 @@
if(!str)
return s;
- if(p->s->caps & CAP_UNICODE){
+ if(p->s->flags2 & FL2_UNICODE){
if(((p->pos - p->buf) % 2) != 0)
p8(p, 0); /* pad to even offset */
while(*str){
@@ -238,7 +238,10 @@
if(!n || !str)
return;
- if(p->s->caps & CAP_UNICODE){
+ if(p->flags2 & FL2_UNICODE){
+ if(((p->pos - p->buf) % 2) != 0)
+ g8(p); /* strip padding to even offset */
+
i = 0;
while(*p->pos && n && p->pos < p->eop){
r = gl16(p);
--- a/sys/src/cmd/cifs/remsmb.h
+++ b/sys/src/cmd/cifs/remsmb.h
@@ -48,11 +48,11 @@
#ifndef _REMDEF_
#define _REMDEF_
-/*
- * ====================================================================
- * SMB XACT message descriptors.
- * ====================================================================
- */
+//====================================================================
+//
+/* SMB XACT message descriptors. */
+//
+//====================================================================
#define REMSmb_share_info_0 "B13"
#define REMSmb_share_info_1 "B13BWz"
@@ -402,11 +402,11 @@
#define REMSmb_LocalOnlyCall ""
-/*
- * The following definitions exist for DOS LANMAN--Windows 3.0.
- * Normally, there is a const char far * servername
- * as the first parameter, but this will be ignored (sort of).
- */
+//
+/* The following definitions exist for DOS LANMAN--Windows 3.0 */
+/* Normally, there is a const char far * servername */
+/* as the first parameter, but this will be ignored (sort of) */
+//
#define REMSmb_DosPrintJobGetId_P "WrL"
#define REMSmb_GetPrintId "WB16B13B"
#define REMSmb_NetRemoteCopy_P "zzzzWWrL"
@@ -458,9 +458,9 @@
#define REMSmb_NetAccountConfirmUpd_P "b12g12D"
#define REMSmb_update_info_0 "K"
-/*
- * SamrOemChangePasswordUser2 api support
- */
-#define REMSmb_SamOEMChgPasswordUser2 "B516B16" /* data that is passed */
+//
+/* SamrOemChangePasswordUser2 api support */
+//
+#define REMSmb_SamOEMChgPasswordUser2 "B516B16" /* data that is passed */
#endif /* ndef _REMDEF_ */
--- a/sys/src/cmd/cifs/trans.c
+++ b/sys/src/cmd/cifs/trans.c
@@ -16,7 +16,7 @@
p->tbase = pl16(p, 0); /* 0 Total parameter bytes to be sent, filled later */
pl16(p, 0); /* 2 Total data bytes to be sent, filled later */
pl16(p, 64); /* 4 Max parameter to return */
- pl16(p, MTU - T2HDRLEN - 128); /* 6 Max data to return */
+ pl16(p, s->mtu - T2HDRLEN - 128); /* 6 Max data to return */
pl16(p, 1); /* 8 Max setup count to return */
pl16(p, 0); /* 10 Flags */
pl32(p, 1000); /* 12 Timeout (ms) */
@@ -126,7 +126,7 @@
pascii(p, REMSmb_NetShareEnum_P); /* request descriptor */
pascii(p, REMSmb_share_info_0); /* reply descriptor */
pl16(p, 0); /* detail level */
- pl16(p, MTU - 200); /* receive buffer length */
+ pl16(p, s->mtu - 1024); /* receive buffer length */
ptdata(p);
if(trpc(p) == -1){
@@ -183,7 +183,7 @@
pascii(p, REMSmb_share_info_2); /* reply descriptor */
pascii(p, share);
pl16(p, 1); /* detail level */
- pl16(p, MTU - 200); /* receive buffer length */
+ pl16(p, s->mtu - 1024); /* receive buffer length */
ptdata(p);
@@ -252,7 +252,7 @@
pascii(p, REMSmb_NetSessionEnum_P); /* request descriptor */
pascii(p, REMSmb_session_info_10); /* reply descriptor */
pl16(p, 10); /* detail level */
- pl16(p, MTU - 200); /* receive buffer length */
+ pl16(p, s->mtu - 1024); /* receive buffer length */
ptdata(p);
if(trpc(p) == -1){
@@ -312,7 +312,7 @@
pascii(p, REMSmb_NetGroupEnum_P); /* request descriptor */
pascii(p, REMSmb_group_info_0); /* reply descriptor */
pl16(p, 0); /* detail level */
- pl16(p, MTU - 200); /* receive buffer length */
+ pl16(p, s->mtu - 1024); /* receive buffer length */
ptdata(p);
if(trpc(p) == -1){
@@ -368,7 +368,7 @@
pascii(p, REMSmb_user_info_0); /* reply descriptor */
pascii(p, group); /* group name for list */
pl16(p, 0); /* detail level */
- pl16(p, MTU - 200); /* receive buffer length */
+ pl16(p, s->mtu - 1024); /* receive buffer length */
ptdata(p);
if(trpc(p) == -1){
@@ -422,7 +422,7 @@
pascii(p, REMSmb_NetUserEnum_P); /* request descriptor */
pascii(p, REMSmb_user_info_0); /* reply descriptor */
pl16(p, 0); /* detail level */
- pl16(p, MTU - 200); /* receive buffer length */
+ pl16(p, s->mtu - 1024); /* receive buffer length */
ptdata(p);
if(trpc(p) == -1){
@@ -478,7 +478,7 @@
pascii(p, REMSmb_NetUserEnum2_P); /* request descriptor */
pascii(p, REMSmb_user_info_0); /* reply descriptor */
pl16(p, 0); /* detail level */
- pl16(p, MTU - 200); /* receive buffer length */
+ pl16(p, s->mtu - 1024); /* receive buffer length */
pl32(p, resume); /* resume key to allow multiple fetches */
ptdata(p);
@@ -536,7 +536,7 @@
pascii(p, REMSmb_user_info_10); /* reply descriptor */
pascii(p, user); /* username */
pl16(p, 10); /* detail level */
- pl16(p, MTU - 200); /* receive buffer length */
+ pl16(p, s->mtu - 1024); /* receive buffer length */
ptdata(p);
if(trpc(p) == -1){
@@ -592,7 +592,7 @@
pascii(p, REMSmb_NetServerEnum2_P); /* request descriptor */
pascii(p, REMSmb_server_info_1); /* reply descriptor */
pl16(p, 1); /* detail level */
- pl16(p, MTU - 200); /* receive buffer length */
+ pl16(p, s->mtu - 1024); /* receive buffer length */
pl32(p, type);
pascii(p, workgroup);
@@ -655,7 +655,7 @@
pascii(p, REMSmb_NetServerEnum3_P); /* request descriptor */
pascii(p, REMSmb_server_info_1); /* reply descriptor */
pl16(p, 1); /* detail level */
- pl16(p, MTU - 200); /* receive buffer length */
+ pl16(p, s->mtu - 1024); /* receive buffer length */
pl32(p, type);
pascii(p, workgroup);
pascii(p, first);
@@ -731,7 +731,7 @@
pascii(p, path);
pascii(p, user);
pl16(p, 1); /* detail level */
- pl16(p, MTU - 200); /* receive buffer length */
+ pl16(p, s->mtu - 1024); /* receive buffer length */
pl32(p, resume); /* resume key */
/* FIXME: maybe the padding and resume key are the wrong way around? */
pl32(p, 0); /* padding ? */
--- a/sys/src/cmd/cifs/trans2.c
+++ b/sys/src/cmd/cifs/trans2.c
@@ -15,7 +15,7 @@
p->tbase = pl16(p, 0); /* 0 Total parameter bytes to be sent, filled later */
pl16(p, 0); /* 2 Total data bytes to be sent, filled later */
pl16(p, 64); /* 4 Max parameter to return */
- pl16(p, (MTU - T2HDRLEN)-64); /* 6 Max data to return */
+ pl16(p, (s->mtu - T2HDRLEN)-64); /* 6 Max data to return */
p8(p, 0); /* 8 Max setup count to return */
p8(p, 0); /* 9 Reserved */
pl16(p, 0); /* 10 Flags */