cifs: updated cifs/smb client to quintiles latest version
This commit is contained in:
parent
b15accceac
commit
8f5375fa61
13 changed files with 388 additions and 341 deletions
|
@ -20,6 +20,9 @@ cifs - Microsoft™ Windows network filesystem client
|
||||||
] [
|
] [
|
||||||
.B -m
|
.B -m
|
||||||
.I mntpnt
|
.I mntpnt
|
||||||
|
] [
|
||||||
|
.B -t
|
||||||
|
.I dfs-timeout
|
||||||
]
|
]
|
||||||
.I host
|
.I host
|
||||||
[
|
[
|
||||||
|
@ -32,8 +35,7 @@ translates between Microsoft's file-sharing protocol
|
||||||
(shares or trees in MS terminology) published by such servers.
|
(shares or trees in MS terminology) published by such servers.
|
||||||
.PP
|
.PP
|
||||||
The root of the mounted directory contains one subdirectory per share,
|
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
|
and a few virtual files give additional information.
|
||||||
give additional server, session, share, and user information.
|
|
||||||
The arguments are:
|
The arguments are:
|
||||||
.TF "-a\fI auth-method"
|
.TF "-a\fI auth-method"
|
||||||
.PD
|
.PD
|
||||||
|
@ -71,6 +73,14 @@ CIFS packet debug.
|
||||||
.B -D
|
.B -D
|
||||||
9P request debug.
|
9P request debug.
|
||||||
.TP
|
.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"
|
.BI -k " keyparam"
|
||||||
lists extra parameters which will be passed to
|
lists extra parameters which will be passed to
|
||||||
.IR factotum (4)
|
.IR factotum (4)
|
||||||
|
@ -112,6 +122,11 @@ and finally it will try the name
|
||||||
post the service as
|
post the service as
|
||||||
.BI /srv/ srvname.
|
.BI /srv/ srvname.
|
||||||
.TP
|
.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
|
.I host
|
||||||
The address of the remote server to connect to.
|
The address of the remote server to connect to.
|
||||||
.TP
|
.TP
|
||||||
|
@ -126,7 +141,7 @@ Several synthetic files appear in the root of the mounted filesystem:
|
||||||
.TP
|
.TP
|
||||||
.B Shares
|
.B Shares
|
||||||
Contains a list of the currently attached 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.
|
and a descriptive comment from the server.
|
||||||
.TP
|
.TP
|
||||||
.B Connection
|
.B Connection
|
||||||
|
@ -161,27 +176,48 @@ the version number of the OS it is running, and comma-separated list of flags
|
||||||
giving the features of that OS.
|
giving the features of that OS.
|
||||||
.TP
|
.TP
|
||||||
.B Dfsroot
|
.B Dfsroot
|
||||||
Top level DFS routing giving the DFS link type, time to live of the data,
|
Lists the top level DFS domains and the servers that
|
||||||
proximity of the server, the Netbios or DNS name and
|
provision them.
|
||||||
a physical path or a machine that this maps to.
|
.TP
|
||||||
.IP
|
.B Dfscache
|
||||||
DNS paths are usually assigned dynamicially as a form of load balancing.
|
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
|
.SH SOURCE
|
||||||
.B /sys/src/cmd/cifs
|
.B /sys/src/cmd/cifs
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.IR factotum (4),
|
.IR factotum (4),
|
||||||
.IR cifsd (8)
|
.IR aquarela (8)
|
||||||
.SH BUGS
|
.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
|
.PP
|
||||||
DFS support is unfinished.
|
Kerberos authentication is not supported.
|
||||||
.PP
|
|
||||||
Kerberos authentication is unfinished.
|
|
||||||
.PP
|
.PP
|
||||||
NetBios name resolution is not supported, though it is now rarely used.
|
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.
|
|
||||||
|
|
|
@ -137,30 +137,28 @@ hmac_t64(uchar *data, ulong dlen, uchar *key, ulong klen, uchar *digest,
|
||||||
static int
|
static int
|
||||||
ntv2_blob(uchar *blob, int len, char *windom)
|
ntv2_blob(uchar *blob, int len, char *windom)
|
||||||
{
|
{
|
||||||
int n;
|
uvlong t;
|
||||||
uvlong nttime;
|
|
||||||
Rune r;
|
|
||||||
char *d;
|
|
||||||
uchar *p;
|
uchar *p;
|
||||||
enum { /* name types */
|
enum { /* name types */
|
||||||
Beof, /* end of name list */
|
Beof, /* end of name list */
|
||||||
Bnetbios, /* Netbios machine name */
|
Bhost, /* Netbios host name */
|
||||||
Bdomain, /* Windows Domain name (NT) */
|
Bdomain, /* Windows Domain name (NT) */
|
||||||
Bdnsfqdn, /* DNS Fully Qualified Domain Name */
|
Bdnshost, /* DNS host name */
|
||||||
Bdnsname, /* DNS machine name (win2k) */
|
Bdnsdomain, /* DNS domain name */
|
||||||
};
|
};
|
||||||
|
|
||||||
p = blob;
|
p = blob;
|
||||||
*p++ = 1; /* response type */
|
*p++ = 1; /* 8bit: response type */
|
||||||
*p++ = 1; /* max response type understood by client */
|
*p++ = 1; /* 8bit: max response type understood by client */
|
||||||
|
|
||||||
|
*p++ = 0; /* 16bit: reserved */
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
*p++ = 0; /* 2 bytes reserved */
|
|
||||||
|
|
||||||
|
*p++ = 0; /* 32bit: unknown */
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
*p++ = 0; /* 4 bytes unknown */
|
|
||||||
|
|
||||||
#ifdef NTLMV2_TEST
|
#ifdef NTLMV2_TEST
|
||||||
*p++ = 0xf0;
|
*p++ = 0xf0;
|
||||||
|
@ -172,18 +170,19 @@ ntv2_blob(uchar *blob, int len, char *windom)
|
||||||
*p++ = 0xbe;
|
*p++ = 0xbe;
|
||||||
*p++ = 0x01;
|
*p++ = 0x01;
|
||||||
#else
|
#else
|
||||||
nttime = time(nil); /* nt time now */
|
t = time(nil); /* 64bit: time in NT format */
|
||||||
nttime = nttime + 11644473600LL;
|
t += 11644473600LL;
|
||||||
nttime = nttime * 10000000LL;
|
t *= 10000000LL;
|
||||||
*p++ = nttime & 0xff;
|
*p++ = t;
|
||||||
*p++ = (nttime >> 8) & 0xff;
|
*p++ = t >> 8;
|
||||||
*p++ = (nttime >> 16) & 0xff;
|
*p++ = t >> 16;
|
||||||
*p++ = (nttime >> 24) & 0xff;
|
*p++ = t >> 24;
|
||||||
*p++ = (nttime >> 32) & 0xff;
|
*p++ = t >> 32;
|
||||||
*p++ = (nttime >> 40) & 0xff;
|
*p++ = t >> 40;
|
||||||
*p++ = (nttime >> 48) & 0xff;
|
*p++ = t >> 48;
|
||||||
*p++ = (nttime >> 56) & 0xff;
|
*p++ = t >> 56;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NTLMV2_TEST
|
#ifdef NTLMV2_TEST
|
||||||
*p++ = 0x05;
|
*p++ = 0x05;
|
||||||
*p++ = 0x83;
|
*p++ = 0x83;
|
||||||
|
@ -195,38 +194,17 @@ ntv2_blob(uchar *blob, int len, char *windom)
|
||||||
*p++ = 0x6d;
|
*p++ = 0x6d;
|
||||||
#else
|
#else
|
||||||
genrandom(p, 8);
|
genrandom(p, 8);
|
||||||
p += 8; /* client nonce */
|
p += 8; /* 64bit: client nonce */
|
||||||
#endif
|
#endif
|
||||||
*p++ = 0x6f;
|
|
||||||
*p++ = 0;
|
|
||||||
*p++ = 0x6e;
|
|
||||||
*p++ = 0; /* unknown data */
|
|
||||||
|
|
||||||
*p++ = Bdomain;
|
*p++ = 0; /* 32bit: unknown data */
|
||||||
*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;
|
|
||||||
*p++ = Beof; /* name type */
|
|
||||||
|
|
||||||
*p++ = 0;
|
|
||||||
*p++ = 0; /* name length */
|
|
||||||
|
|
||||||
*p++ = 0x65;
|
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
*p++ = 0; /* unknown data */
|
*p++ = 0;
|
||||||
|
|
||||||
|
p += putname(p, len - (p-blob), windom, Bdomain);
|
||||||
|
p += putname(p, len - (p-blob), "", Beof);
|
||||||
|
|
||||||
return p - blob;
|
return p - blob;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,77 +135,80 @@ hmac_t64(uchar *data, ulong dlen, uchar *key, ulong klen, uchar *digest,
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ntv2_blob(uchar *blob, int len, char *windom)
|
putname(uchar *buf, int len, char *name, int type)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
uvlong nttime;
|
|
||||||
Rune r;
|
Rune r;
|
||||||
char *d;
|
char *d;
|
||||||
uchar *p;
|
uchar *p = buf;
|
||||||
enum { /* name types */
|
|
||||||
Beof, /* end of name list */
|
|
||||||
Bnetbios, /* Netbios machine name */
|
|
||||||
Bdomain, /* Windows Domain name (NT) */
|
|
||||||
Bdnsfqdn, /* DNS Fully Qualified Domain Name */
|
|
||||||
Bdnsname, /* DNS machine name (win2k) */
|
|
||||||
};
|
|
||||||
|
|
||||||
p = blob;
|
*p++ = type;
|
||||||
*p++ = 1; /* response type */
|
*p++ = 0; /* 16bit: name type */
|
||||||
*p++ = 1; /* max response type understood by client */
|
|
||||||
|
|
||||||
*p++ = 0;
|
n = utflen(name) * 2;
|
||||||
*p++ = 0; /* 2 bytes reserved */
|
|
||||||
|
|
||||||
*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;
|
|
||||||
|
|
||||||
genrandom(p, 8);
|
|
||||||
p += 8; /* client nonce */
|
|
||||||
*p++ = 0x6f;
|
|
||||||
*p++ = 0;
|
|
||||||
*p++ = 0x6e;
|
|
||||||
*p++ = 0; /* unknown data */
|
|
||||||
|
|
||||||
*p++ = Bdomain;
|
|
||||||
*p++ = 0; /* name type */
|
|
||||||
|
|
||||||
n = utflen(windom) * 2;
|
|
||||||
*p++ = n;
|
*p++ = n;
|
||||||
*p++ = n >> 8; /* name length */
|
*p++ = n >> 8; /* 16bit: name length */
|
||||||
|
|
||||||
d = windom;
|
d = name;
|
||||||
while(*d && p-blob < (len-8)){
|
while(*d != 0 && p-buf < len-8){
|
||||||
d += chartorune(&r, d);
|
d += chartorune(&r, d);
|
||||||
r = toupperrune(r);
|
r = toupperrune(r);
|
||||||
*p++ = r;
|
*p++ = r;
|
||||||
*p++ = r >> 8;
|
*p++ = r >> 8;
|
||||||
}
|
} /* var: actual name */
|
||||||
|
|
||||||
*p++ = 0;
|
return p - buf;
|
||||||
*p++ = Beof; /* name type */
|
}
|
||||||
|
|
||||||
*p++ = 0;
|
static int
|
||||||
*p++ = 0; /* name length */
|
ntv2_blob(uchar *blob, int len, char *windom)
|
||||||
|
{
|
||||||
|
uvlong t;
|
||||||
|
uchar *p;
|
||||||
|
enum { /* name types */
|
||||||
|
Beof, /* end of name list */
|
||||||
|
Bhost, /* Netbios host name */
|
||||||
|
Bdomain, /* Windows Domain name (NT) */
|
||||||
|
Bdnshost, /* DNS host name */
|
||||||
|
Bdnsdomain, /* DNS domain name */
|
||||||
|
};
|
||||||
|
|
||||||
*p++ = 0x65;
|
p = blob;
|
||||||
|
*p++ = 1; /* 8bit: response type */
|
||||||
|
*p++ = 1; /* 8bit: max response type understood by client */
|
||||||
|
|
||||||
|
*p++ = 0; /* 16bit: reserved */
|
||||||
|
*p++ = 0;
|
||||||
|
|
||||||
|
*p++ = 0; /* 32bit: unknown */
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
*p++ = 0; /* unknown data */
|
*p++ = 0;
|
||||||
|
|
||||||
|
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; /* 64bit: client nonce */
|
||||||
|
|
||||||
|
*p++ = 0; /* 32bit: unknown data */
|
||||||
|
*p++ = 0;
|
||||||
|
*p++ = 0;
|
||||||
|
*p++ = 0;
|
||||||
|
|
||||||
|
p += putname(p, len - (p-blob), windom, Bdomain);
|
||||||
|
p += putname(p, len - (p-blob), "", Beof);
|
||||||
|
|
||||||
return p - blob;
|
return p - blob;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,7 +296,7 @@ auth_ntlmv2(char *windom, char *keyp, uchar *chal, int len)
|
||||||
memcpy(ap->mackey[0]+MD5dlen, ap->resp[0], MACkeylen-MD5dlen);
|
memcpy(ap->mackey[0]+MD5dlen, ap->resp[0], MACkeylen-MD5dlen);
|
||||||
|
|
||||||
/* NTLM v2 */
|
/* 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);
|
ds = hmac_t64(chal, len, v2hash, MD5dlen, nil, nil);
|
||||||
hmac_t64(blob, n, v2hash, MD5dlen, nt_hmac, ds);
|
hmac_t64(blob, n, v2hash, MD5dlen, nt_hmac, ds);
|
||||||
ap->len[1] = MD5dlen+n;
|
ap->len[1] = MD5dlen+n;
|
||||||
|
|
|
@ -40,8 +40,12 @@ cifsdial(char *host, char *called, char *sysname)
|
||||||
s->seqrun = 0;
|
s->seqrun = 0;
|
||||||
s->secmode = SECMODE_SIGN_ENABLED; /* hope for the best */
|
s->secmode = SECMODE_SIGN_ENABLED; /* hope for the best */
|
||||||
s->flags2 = FL2_KNOWS_LONG_NAMES | FL2_HAS_LONG_NAMES | FL2_PAGEING_IO;
|
s->flags2 = FL2_KNOWS_LONG_NAMES | FL2_HAS_LONG_NAMES | FL2_PAGEING_IO;
|
||||||
|
|
||||||
s->macidx = -1;
|
s->macidx = -1;
|
||||||
|
|
||||||
|
if(s->mtu > MTU)
|
||||||
|
s->mtu = MTU;
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +80,7 @@ cifshdr(Session *s, Share *sp, int cmd)
|
||||||
|
|
||||||
p->buf = (uchar *)p + sizeof(Pkt);
|
p->buf = (uchar *)p + sizeof(Pkt);
|
||||||
p->s = s;
|
p->s = s;
|
||||||
|
p->request = cmd; /* for debug */
|
||||||
|
|
||||||
qlock(&s->seqlock);
|
qlock(&s->seqlock);
|
||||||
if(s->seqrun){
|
if(s->seqrun){
|
||||||
|
@ -137,11 +142,12 @@ dmp(int seq, uchar *buf)
|
||||||
int
|
int
|
||||||
cifsrpc(Pkt *p)
|
cifsrpc(Pkt *p)
|
||||||
{
|
{
|
||||||
int flags2, got, err;
|
int reply, got, err;
|
||||||
uint tid, uid, seq;
|
uint tid, uid, seq;
|
||||||
uchar *pos;
|
uchar *pos;
|
||||||
char m[nelem(magic)];
|
char m[nelem(magic)];
|
||||||
|
|
||||||
|
|
||||||
pos = p->pos;
|
pos = p->pos;
|
||||||
if(p->bytebase){
|
if(p->bytebase){
|
||||||
p->pos = p->bytebase;
|
p->pos = p->bytebase;
|
||||||
|
@ -155,20 +161,23 @@ cifsrpc(Pkt *p)
|
||||||
qlock(&p->s->rpclock);
|
qlock(&p->s->rpclock);
|
||||||
got = nbtrpc(p);
|
got = nbtrpc(p);
|
||||||
qunlock(&p->s->rpclock);
|
qunlock(&p->s->rpclock);
|
||||||
if(got == -1)
|
|
||||||
|
if(got < 32+NBHDRLEN){
|
||||||
|
werrstr("cifs packet too small (%d < %d)\n", got, 32+NBHDRLEN);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
gmem(p, m, nelem(magic));
|
gmem(p, m, nelem(magic));
|
||||||
if(memcmp(m, magic, nelem(magic)) != 0){
|
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]);
|
m[0], m[1], m[2], m[3]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
g8(p); /* cmd */
|
reply = g8(p); /* cmd */
|
||||||
err = gl32(p); /* errcode */
|
err = gl32(p); /* errcode */
|
||||||
g8(p); /* flags */
|
g8(p); /* flags */
|
||||||
flags2 = gl16(p); /* flags2 */
|
p->flags2 = gl16(p); /* flags2 */
|
||||||
gl16(p); /* PID MS bits */
|
gl16(p); /* PID MS bits */
|
||||||
seq = gl32(p); /* reserved */
|
seq = gl32(p); /* reserved */
|
||||||
gl32(p); /* MAC (if in use) */
|
gl32(p); /* MAC (if in use) */
|
||||||
|
@ -179,6 +188,12 @@ cifsrpc(Pkt *p)
|
||||||
gl16(p); /* mid */
|
gl16(p); /* mid */
|
||||||
g8(p); /* word count */
|
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(p->s->secmode & SECMODE_SIGN_ENABLED){
|
||||||
if(macsign(p, p->seq+1) != 0 && p->s->seqrun){
|
if(macsign(p, p->seq+1) != 0 && p->s->seqrun){
|
||||||
werrstr("cifsrpc: invalid packet signature");
|
werrstr("cifsrpc: invalid packet signature");
|
||||||
|
@ -196,7 +211,7 @@ print("MAC signature bad\n");
|
||||||
* catch that too.
|
* catch that too.
|
||||||
*/
|
*/
|
||||||
if(p->s->seqrun && seq != p->seq && seq != 0){
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,7 +220,7 @@ print("MAC signature bad\n");
|
||||||
if(p->s->uid == NO_UID)
|
if(p->s->uid == NO_UID)
|
||||||
p->s->uid = 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? */
|
/* is it a real error rather than info/warning/chatter? */
|
||||||
if((err & 0xF0000000) == 0xC0000000){
|
if((err & 0xF0000000) == 0xC0000000){
|
||||||
werrstr("%s", nterrstr(err));
|
werrstr("%s", nterrstr(err));
|
||||||
|
@ -243,11 +258,26 @@ CIFSnegotiate(Session *s, long *svrtime, char *domain, int domlen, char *cname,
|
||||||
};
|
};
|
||||||
Pkt *p;
|
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);
|
p = cifshdr(s, nil, SMB_COM_NEGOTIATE);
|
||||||
|
s->flags2 &= ~FL2_UNICODE;
|
||||||
|
|
||||||
pbytes(p);
|
pbytes(p);
|
||||||
for(i = 0; i < nelem(dialects); i++){
|
for(i = 0; i < nelem(dialects); i++){
|
||||||
p8(p, STR_DIALECT);
|
p8(p, STR_DIALECT);
|
||||||
pstr(p, dialects[i]);
|
pascii(p, dialects[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cifsrpc(p) == -1){
|
if(cifsrpc(p) == -1){
|
||||||
|
@ -368,7 +398,7 @@ CIFSsession(Session *s)
|
||||||
gl16(p);
|
gl16(p);
|
||||||
gl16(p);
|
gl16(p);
|
||||||
/* no security blob here - we don't understand extended security anyway */
|
/* 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);
|
s->remos = estrdup9p(os);
|
||||||
|
|
||||||
free(p);
|
free(p);
|
||||||
|
@ -386,9 +416,9 @@ CIFStreeconnect(Session *s, char *cname, char *tree, Share *sp)
|
||||||
resp = Sess->auth->resp[0];
|
resp = Sess->auth->resp[0];
|
||||||
len = Sess->auth->len[0];
|
len = Sess->auth->len[0];
|
||||||
if((s->secmode & SECMODE_USER) != SECMODE_USER){
|
if((s->secmode & SECMODE_USER) != SECMODE_USER){
|
||||||
memset(zeros, 0, sizeof(zeros));
|
memset(zeros, 0, sizeof zeros);
|
||||||
resp = zeros;
|
resp = zeros;
|
||||||
len = sizeof(zeros);
|
len = sizeof zeros;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = cifshdr(s, nil, SMB_COM_TREE_CONNECT_ANDX);
|
p = cifshdr(s, nil, SMB_COM_TREE_CONNECT_ANDX);
|
||||||
|
@ -408,7 +438,7 @@ CIFStreeconnect(Session *s, char *cname, char *tree, Share *sp)
|
||||||
}
|
}
|
||||||
|
|
||||||
path = smprint("//%s/%s", cname, tree);
|
path = smprint("//%s/%s", cname, tree);
|
||||||
strupr(path);
|
|
||||||
ppath(p, path); /* path */
|
ppath(p, path); /* path */
|
||||||
free(path);
|
free(path);
|
||||||
|
|
||||||
|
|
|
@ -350,10 +350,10 @@ typedef struct {
|
||||||
int uid; /* user (authentication) ID */
|
int uid; /* user (authentication) ID */
|
||||||
int seq; /* sequence number */
|
int seq; /* sequence number */
|
||||||
int seqrun; /* sequence numbering active */
|
int seqrun; /* sequence numbering active */
|
||||||
int caps; /* server capabilities */
|
int caps; /* server's capabilities */
|
||||||
int support; /* support bits */
|
int support; /* support bits */
|
||||||
int flags; /* SMB flags */
|
int flags; /* SMB flags that we will send in the next packet */
|
||||||
int flags2; /* SMB flags 2 */
|
int flags2; /* SMB flags 2 that we will send in the next packet */
|
||||||
int nocache; /* disable write behind caching in server */
|
int nocache; /* disable write behind caching in server */
|
||||||
int pid; /* process ID */
|
int pid; /* process ID */
|
||||||
int mid; /* multiplex ID */
|
int mid; /* multiplex ID */
|
||||||
|
@ -378,6 +378,8 @@ typedef struct {
|
||||||
|
|
||||||
int tid; /* tree ID received from server */
|
int tid; /* tree ID received from server */
|
||||||
int seq; /* sequence number expected in reply */
|
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 *seqbase; /* cifs: pos of sequence number in packet */
|
||||||
uchar *wordbase; /* cifs: base of words section of data */
|
uchar *wordbase; /* cifs: base of words section of data */
|
||||||
|
@ -483,156 +485,150 @@ extern Share Ipc;
|
||||||
extern Share Shares[MAX_SHARES];
|
extern Share Shares[MAX_SHARES];
|
||||||
extern int Nshares;
|
extern int Nshares;
|
||||||
|
|
||||||
/* main.c */
|
|
||||||
Qid mkqid(char *, int, long, int, long);
|
|
||||||
|
|
||||||
/* auth.c */
|
/* auth.c */
|
||||||
Auth *getauth(char *, char *, char *, int, uchar *, int);
|
extern void autherr(void);
|
||||||
void autherr(void);
|
extern Auth *getauth(char *name, char *windom, char *keyp, int secmode, uchar *chal, int len);
|
||||||
int macsign(Pkt *, int);
|
extern int macsign(Pkt *p, int seq);
|
||||||
|
|
||||||
/* cifs.c */
|
/* cifs.c */
|
||||||
Session *cifsdial(char *, char *, char *);
|
extern Session *cifsdial(char *host, char *called, char *sysname);
|
||||||
void cifsclose(Session *);
|
extern void cifsclose(Session *s);
|
||||||
Pkt *cifshdr(Session *, Share *, int);
|
extern Pkt *cifshdr(Session *s, Share *sp, int cmd);
|
||||||
void pbytes(Pkt *);
|
extern void pbytes(Pkt *p);
|
||||||
int cifsrpc(Pkt *);
|
extern int cifsrpc(Pkt *p);
|
||||||
int CIFSnegotiate(Session *, long *, char *, int, char *, int);
|
extern int CIFSnegotiate(Session *s, long *svrtime, char *domain, int domlen, char *cname, int cnamlen);
|
||||||
int CIFSsession(Session *);
|
extern int CIFSsession(Session *s);
|
||||||
int CIFStreeconnect(Session *, char *, char *, Share *);
|
extern int CIFStreeconnect(Session *s, char *cname, char *tree, Share *sp);
|
||||||
int CIFSlogoff(Session *);
|
extern int CIFSlogoff(Session *s);
|
||||||
int CIFStreedisconnect(Session *, Share *);
|
extern int CIFStreedisconnect(Session *s, Share *sp);
|
||||||
int CIFSdeletefile(Session *, Share *, char *);
|
extern int CIFSdeletefile(Session *s, Share *sp, char *name);
|
||||||
int CIFSdeletedirectory(Session *, Share *, char *);
|
extern int CIFSdeletedirectory(Session *s, Share *sp, char *name);
|
||||||
int CIFScreatedirectory(Session *, Share *, char *);
|
extern int CIFScreatedirectory(Session *s, Share *sp, char *name);
|
||||||
int CIFSrename(Session *, Share *, char *, char *);
|
extern int CIFSrename(Session *s, Share *sp, char *old, char *new);
|
||||||
int CIFS_NT_opencreate(Session *, Share *, char *, int, int, int, int, int, int, int *, FInfo *);
|
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);
|
||||||
int CIFS_SMB_opencreate(Session *, Share *, char *, int, int, int, int *);
|
extern int CIFS_SMB_opencreate(Session *s, Share *sp, char *name, int access, int attrs, int action, int *result);
|
||||||
vlong CIFSwrite(Session *, Share *, int, uvlong, void *, vlong);
|
extern vlong CIFSwrite(Session *s, Share *sp, int fh, uvlong off, void *buf, vlong n);
|
||||||
vlong CIFSread(Session *, Share *, int, uvlong, void *, vlong, vlong);
|
extern vlong CIFSread(Session *s, Share *sp, int fh, uvlong off, void *buf, vlong n, vlong minlen);
|
||||||
int CIFSflush(Session *, Share *, int);
|
extern int CIFSflush(Session *s, Share *sp, int fh);
|
||||||
int CIFSclose(Session *, Share *, int);
|
extern int CIFSclose(Session *s, Share *sp, int fh);
|
||||||
int CIFSfindclose2(Session *, Share *, int);
|
extern int CIFSfindclose2(Session *s, Share *sp, int sh);
|
||||||
int CIFSecho(Session *);
|
extern int CIFSecho(Session *s);
|
||||||
int CIFSsetinfo(Session *, Share *, char *, FInfo *);
|
extern int CIFSsetinfo(Session *s, Share *sp, char *path, FInfo *fip);
|
||||||
void goff(Pkt *, uchar *, char *, int);
|
|
||||||
|
|
||||||
/* dfs.c */
|
/* dfs.c */
|
||||||
char *mapfile(char *);
|
extern int dfscacheinfo(Fmt *f);
|
||||||
int mapshare(char *, Share **);
|
extern char *trimshare(char *s);
|
||||||
int redirect(Session *, Share *s, char *);
|
extern char *mapfile(char *opath);
|
||||||
int dfscacheinfo(Fmt *);
|
extern int mapshare(char *path, Share **osp);
|
||||||
char *trimshare(char *);
|
extern int redirect(Session *s, Share *sp, char *path);
|
||||||
|
|
||||||
/* doserrstr.c */
|
/* doserrstr.c */
|
||||||
char *doserrstr(uint);
|
extern char *doserrstr(uint err);
|
||||||
|
|
||||||
/* fs.c */
|
/* fs.c */
|
||||||
int shareinfo(Fmt *);
|
extern int shareinfo(Fmt *f);
|
||||||
int conninfo(Fmt *);
|
extern int openfileinfo(Fmt *f);
|
||||||
int sessioninfo(Fmt *);
|
extern int conninfo(Fmt *f);
|
||||||
int userinfo(Fmt *);
|
extern int sessioninfo(Fmt *f);
|
||||||
int groupinfo(Fmt *);
|
extern int dfsrootinfo(Fmt *f);
|
||||||
int domaininfo(Fmt *);
|
extern int userinfo(Fmt *f);
|
||||||
int workstationinfo(Fmt *);
|
extern int groupinfo(Fmt *f);
|
||||||
int dfsrootinfo(Fmt *);
|
extern int domaininfo(Fmt *f);
|
||||||
int openfileinfo(Fmt *);
|
extern int workstationinfo(Fmt *f);
|
||||||
int dfsrootinfo(Fmt *);
|
|
||||||
int filetableinfo(Fmt *); /* is in main.c due to C scope */
|
|
||||||
|
|
||||||
/* info.c */
|
/* info.c */
|
||||||
int walkinfo(char *);
|
extern int walkinfo(char *name);
|
||||||
int numinfo(void);
|
extern int numinfo(void);
|
||||||
int dirgeninfo(int, Dir *);
|
extern int dirgeninfo(int slot, Dir *d);
|
||||||
int makeinfo(int);
|
extern int makeinfo(int path);
|
||||||
int readinfo(int, char *, int, int);
|
extern int readinfo(int path, char *buf, int len, int off);
|
||||||
void freeinfo(int);
|
extern void freeinfo(int path);
|
||||||
|
|
||||||
/* main.c */
|
/* main.c */
|
||||||
void usage(void);
|
extern void setup(void);
|
||||||
void dmpkey(char *, void *, int);
|
extern int filetableinfo(Fmt *f);
|
||||||
void main(int, char **);
|
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 */
|
/* misc.c */
|
||||||
char *strupr(char *);
|
extern char *strupr(char *s);
|
||||||
char *strlwr(char *);
|
extern char *strlwr(char *s);
|
||||||
|
|
||||||
/* netbios.c */
|
/* netbios.c */
|
||||||
void Gmem(uchar **, void *, int);
|
extern void Gmem(uchar **p, void *v, int n);
|
||||||
int calledname(char *, char *);
|
extern int calledname(char *host, char *name);
|
||||||
int nbtdial(char *, char *, char *);
|
extern int nbtdial(char *addr, char *called, char *sysname);
|
||||||
void nbthdr(Pkt *);
|
extern void nbthdr(Pkt *p);
|
||||||
int nbtrpc(Pkt *);
|
extern int nbtrpc(Pkt *p);
|
||||||
void xd(char *, void *, int);
|
extern void xd(char *str, void *buf, int n);
|
||||||
|
|
||||||
/* nterrstr.c */
|
/* nterrstr.c */
|
||||||
char *nterrstr(uint);
|
extern char *nterrstr(uint err);
|
||||||
|
|
||||||
/* pack.c */
|
/* pack.c */
|
||||||
void *pmem(Pkt *, void *, int);
|
extern void *pmem(Pkt *p, void *v, int len);
|
||||||
void *ppath(Pkt *, char *);
|
extern void *ppath(Pkt *p, char *str);
|
||||||
void *pstr(Pkt *, char *);
|
extern void *pstr(Pkt *p, char *str);
|
||||||
void *pascii(Pkt *, char *);
|
extern void *pascii(Pkt *p, char *str);
|
||||||
void *pl64(Pkt *, uvlong);
|
extern void *pl64(Pkt *p, uvlong n);
|
||||||
void *pb32(Pkt *, uint);
|
extern void *pb32(Pkt *p, uint n);
|
||||||
void *pl32(Pkt *, uint);
|
extern void *pl32(Pkt *p, uint n);
|
||||||
void *pb16(Pkt *, uint);
|
extern void *pb16(Pkt *p, uint n);
|
||||||
void *pl16(Pkt *, uint);
|
extern void *pl16(Pkt *p, uint n);
|
||||||
void *p8(Pkt *, uint);
|
extern void *p8(Pkt *p, uint n);
|
||||||
void *pname(Pkt *, char *, char);
|
extern void *pname(Pkt *p, char *name, char pad);
|
||||||
void *pvtime(Pkt *, uvlong);
|
extern void *pvtime(Pkt *p, uvlong n);
|
||||||
void *pdatetime(Pkt *, long);
|
extern void *pdatetime(Pkt *p, long utc);
|
||||||
void gmem(Pkt *, void *, int);
|
extern void gmem(Pkt *p, void *v, int n);
|
||||||
void gstr(Pkt *, char *, int);
|
extern void gstr(Pkt *p, char *str, int n);
|
||||||
void gascii(Pkt *, char *, int);
|
extern void gascii(Pkt *p, char *str, int n);
|
||||||
uvlong gl64(Pkt *);
|
extern uvlong gl64(Pkt *p);
|
||||||
uvlong gb48(Pkt *);
|
extern uvlong gb48(Pkt *p);
|
||||||
uint gb32(Pkt *);
|
extern uint gb32(Pkt *p);
|
||||||
uint gl32(Pkt *);
|
extern uint gl32(Pkt *p);
|
||||||
uint gb16(Pkt *);
|
extern uint gb16(Pkt *p);
|
||||||
uint gl16(Pkt *);
|
extern uint gl16(Pkt *p);
|
||||||
uint g8(Pkt *);
|
extern uint g8(Pkt *p);
|
||||||
long gdatetime(Pkt *);
|
extern long gdatetime(Pkt *p);
|
||||||
long gvtime(Pkt *);
|
extern long gvtime(Pkt *p);
|
||||||
void gconv(Pkt *, int, char *, int);
|
extern void gconv(Pkt *p, int conv, char *str, int n);
|
||||||
|
extern void goff(Pkt *p, uchar *base, char *str, int n);
|
||||||
/* raperrstr.c */
|
|
||||||
char *raperrstr(uint);
|
|
||||||
|
|
||||||
/* sid2name.c */
|
|
||||||
void upd_names(Session *, Share *, char *, Dir *);
|
|
||||||
|
|
||||||
/* trans.c */
|
|
||||||
int RAPshareenum(Session *, Share *, Share **);
|
|
||||||
int RAPshareinfo(Session *, Share *, char *, Shareinfo2 *);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
/* transnt.c */
|
|
||||||
int TNTquerysecurity(Session *, Share *, int, char **, char **);
|
|
||||||
|
|
||||||
/* ping.c */
|
/* ping.c */
|
||||||
int ping(char *, int);
|
extern int ping(char *host, int timeout);
|
||||||
|
|
||||||
|
/* raperrstr.c */
|
||||||
|
extern char *raperrstr(uint err);
|
||||||
|
|
||||||
|
/* sid2name.c */
|
||||||
|
extern void upd_names(Session *s, Share *sp, char *path, Dir *d);
|
||||||
|
|
||||||
|
/* trans.c */
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* trans2.c */
|
||||||
|
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 */
|
||||||
|
extern int TNTquerysecurity(Session *s, Share *sp, int fh, char **usid, char **gsid);
|
||||||
|
|
|
@ -13,17 +13,17 @@ struct {
|
||||||
char *buf;
|
char *buf;
|
||||||
int len;
|
int len;
|
||||||
} Infdir[] = {
|
} Infdir[] = {
|
||||||
{ "Users", userinfo },
|
{ "Users" , userinfo },
|
||||||
{ "Groups", groupinfo },
|
{ "Groups" , groupinfo },
|
||||||
{ "Shares", shareinfo },
|
{ "Shares" , shareinfo },
|
||||||
{ "Connection", conninfo },
|
{ "Connection" , conninfo },
|
||||||
{ "Sessions", sessioninfo },
|
{ "Sessions" , sessioninfo },
|
||||||
{ "Dfsroot", dfsrootinfo },
|
{ "Dfsroot" , dfsrootinfo },
|
||||||
{ "Dfscache", dfscacheinfo },
|
{ "Dfscache" , dfscacheinfo },
|
||||||
{ "Domains", domaininfo },
|
{ "Domains" , domaininfo },
|
||||||
{ "Openfiles", openfileinfo },
|
{ "Openfiles" , openfileinfo },
|
||||||
{ "Workstations", workstationinfo },
|
{ "Workstations" , workstationinfo },
|
||||||
{ "Filetable", filetableinfo },
|
{ "Filetable" , filetableinfo },
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -63,6 +63,7 @@ dirgeninfo(int slot, Dir *d)
|
||||||
d->qid.vers = 1;
|
d->qid.vers = 1;
|
||||||
d->qid.path = slot;
|
d->qid.path = slot;
|
||||||
d->qid.type = 0;
|
d->qid.type = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,10 +77,12 @@ makeinfo(int path)
|
||||||
if(Infdir[path].buf != nil)
|
if(Infdir[path].buf != nil)
|
||||||
return 0;
|
return 0;
|
||||||
fmtstrinit(&f);
|
fmtstrinit(&f);
|
||||||
if((*Infdir[path].func)(&f) == -1l)
|
if((*Infdir[path].func)(&f) == -1)
|
||||||
|
return -1;
|
||||||
|
if((Infdir[path].buf = fmtstrflush(&f)) == nil)
|
||||||
|
return -1;
|
||||||
|
if((Infdir[path].len = strlen(Infdir[path].buf)) <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
Infdir[path].buf = fmtstrflush(&f);
|
|
||||||
Infdir[path].len = strlen(Infdir[path].buf);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,3 +107,4 @@ freeinfo(int path)
|
||||||
free(Infdir[path].buf);
|
free(Infdir[path].buf);
|
||||||
Infdir[path].buf = nil;
|
Infdir[path].buf = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -198,7 +198,9 @@ dirgen(int slot, Dir *d, void *aux)
|
||||||
Aux *a = aux;
|
Aux *a = aux;
|
||||||
char *npath;
|
char *npath;
|
||||||
int numinf = numinfo();
|
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(strcmp(a->path, "/") == 0){
|
||||||
if(slot < numinf){
|
if(slot < numinf){
|
||||||
|
@ -1103,6 +1105,7 @@ keepalive(void)
|
||||||
sleep(6000);
|
sleep(6000);
|
||||||
if(Active-- != 0)
|
if(Active-- != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for(i = 0; i < Nshares; i++){
|
for(i = 0; i < Nshares; i++){
|
||||||
if((rc = T2fssizeinfo(Sess, &Shares[slot], &tot, &fre)) == 0)
|
if((rc = T2fssizeinfo(Sess, &Shares[slot], &tot, &fre)) == 0)
|
||||||
break;
|
break;
|
||||||
|
@ -1253,6 +1256,8 @@ connected:
|
||||||
memcpy(Shares+Nshares, sip+i, sizeof(Share));
|
memcpy(Shares+Nshares, sip+i, sizeof(Share));
|
||||||
if(CIFStreeconnect(Sess, Sess->cname,
|
if(CIFStreeconnect(Sess, Sess->cname,
|
||||||
Shares[Nshares].name, Shares+Nshares) == -1){
|
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);
|
free(Shares[Nshares].name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,3 @@ OFILES= main.$O transnt.$O trans2.$O trans.$O cifs.$O \
|
||||||
auth.$O dfs.$O ping.$O
|
auth.$O dfs.$O ping.$O
|
||||||
|
|
||||||
</sys/src/cmd/mkone
|
</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
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* 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
|
* a problem for native programs but those built on APE
|
||||||
* will give unhelpful errors if this is not done
|
* will give unhelpful errors if this is not done
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
char *msg;
|
char *msg;
|
||||||
|
@ -261,8 +261,8 @@ static struct {
|
||||||
{ "password restriction", 0xc000006c },
|
{ "password restriction", 0xc000006c },
|
||||||
{ "logon failure", 0xc000006d },
|
{ "logon failure", 0xc000006d },
|
||||||
{ "account restriction", 0xc000006e },
|
{ "account restriction", 0xc000006e },
|
||||||
{ "invalid logon hours", 0xc000006f },
|
{ "login disallowed at this time", 0xc000006f },
|
||||||
{ "invalid workstation", 0xc0000070 },
|
{ "login disallowed from this workstation", 0xc0000070 },
|
||||||
{ "password expired", 0xc0000071 },
|
{ "password expired", 0xc0000071 },
|
||||||
{ "account disabled", 0xc0000072 },
|
{ "account disabled", 0xc0000072 },
|
||||||
{ "none mapped", 0xc0000073 },
|
{ "none mapped", 0xc0000073 },
|
||||||
|
@ -959,7 +959,7 @@ static struct {
|
||||||
{ "SXS multiple deactivation", 0xc0150011 },
|
{ "SXS multiple deactivation", 0xc0150011 },
|
||||||
{ "SXS system default activation context empty",0xc0150012 },
|
{ "SXS system default activation context empty",0xc0150012 },
|
||||||
{ "SXS process termination requested", 0xc0150013 },
|
{ "SXS process termination requested", 0xc0150013 },
|
||||||
};
|
};
|
||||||
|
|
||||||
char *
|
char *
|
||||||
nterrstr(uint err)
|
nterrstr(uint err)
|
||||||
|
@ -1006,14 +1006,13 @@ nterrstr(uint err)
|
||||||
match = i;
|
match = i;
|
||||||
|
|
||||||
why = "";
|
why = "";
|
||||||
if(!(err & 0x80000000))
|
if(! (err & 0x80000000))
|
||||||
why = "warning, ";
|
why = "warning, ";
|
||||||
|
|
||||||
if(match != -1)
|
if(match != -1)
|
||||||
snprint(buf, sizeof buf, "%s%s%s", why, facility,
|
snprint(buf, sizeof(buf), "%s%s%s", why, facility, NTerrs[match].msg);
|
||||||
NTerrs[match].msg);
|
|
||||||
else
|
else
|
||||||
snprint(buf, sizeof buf, "%s%s%d/0x%ux - unknown NT error",
|
snprint(buf, sizeof(buf), "%s%s%d/0x%ux - unknown NT error", why, facility, err, err);
|
||||||
why, facility, err, err);
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ ppath(Pkt *p, char *str)
|
||||||
if(!str)
|
if(!str)
|
||||||
return s;
|
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 */
|
if(((p->pos - p->buf) % 2) != 0) /* pad to even offset */
|
||||||
p8(p, 0);
|
p8(p, 0);
|
||||||
while(*str){
|
while(*str){
|
||||||
|
@ -57,7 +57,7 @@ pstr(Pkt *p, char *str)
|
||||||
if(!str)
|
if(!str)
|
||||||
return s;
|
return s;
|
||||||
|
|
||||||
if(p->s->caps & CAP_UNICODE){
|
if(p->s->flags2 & FL2_UNICODE){
|
||||||
if(((p->pos - p->buf) % 2) != 0)
|
if(((p->pos - p->buf) % 2) != 0)
|
||||||
p8(p, 0); /* pad to even offset */
|
p8(p, 0); /* pad to even offset */
|
||||||
while(*str){
|
while(*str){
|
||||||
|
@ -238,7 +238,10 @@ gstr(Pkt *p, char *str, int n)
|
||||||
if(!n || !str)
|
if(!n || !str)
|
||||||
return;
|
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;
|
i = 0;
|
||||||
while(*p->pos && n && p->pos < p->eop){
|
while(*p->pos && n && p->pos < p->eop){
|
||||||
r = gl16(p);
|
r = gl16(p);
|
||||||
|
|
|
@ -48,11 +48,11 @@ Revision History:
|
||||||
|
|
||||||
#ifndef _REMDEF_
|
#ifndef _REMDEF_
|
||||||
#define _REMDEF_
|
#define _REMDEF_
|
||||||
/*
|
//====================================================================
|
||||||
* ====================================================================
|
//
|
||||||
* SMB XACT message descriptors.
|
/* SMB XACT message descriptors. */
|
||||||
* ====================================================================
|
//
|
||||||
*/
|
//====================================================================
|
||||||
|
|
||||||
#define REMSmb_share_info_0 "B13"
|
#define REMSmb_share_info_0 "B13"
|
||||||
#define REMSmb_share_info_1 "B13BWz"
|
#define REMSmb_share_info_1 "B13BWz"
|
||||||
|
@ -402,11 +402,11 @@ Revision History:
|
||||||
|
|
||||||
#define REMSmb_LocalOnlyCall ""
|
#define REMSmb_LocalOnlyCall ""
|
||||||
|
|
||||||
/*
|
//
|
||||||
* The following definitions exist for DOS LANMAN--Windows 3.0.
|
/* The following definitions exist for DOS LANMAN--Windows 3.0 */
|
||||||
* Normally, there is a const char far * servername
|
/* Normally, there is a const char far * servername */
|
||||||
* as the first parameter, but this will be ignored (sort of).
|
/* as the first parameter, but this will be ignored (sort of) */
|
||||||
*/
|
//
|
||||||
#define REMSmb_DosPrintJobGetId_P "WrL"
|
#define REMSmb_DosPrintJobGetId_P "WrL"
|
||||||
#define REMSmb_GetPrintId "WB16B13B"
|
#define REMSmb_GetPrintId "WB16B13B"
|
||||||
#define REMSmb_NetRemoteCopy_P "zzzzWWrL"
|
#define REMSmb_NetRemoteCopy_P "zzzzWWrL"
|
||||||
|
@ -458,9 +458,9 @@ Revision History:
|
||||||
#define REMSmb_NetAccountConfirmUpd_P "b12g12D"
|
#define REMSmb_NetAccountConfirmUpd_P "b12g12D"
|
||||||
#define REMSmb_update_info_0 "K"
|
#define REMSmb_update_info_0 "K"
|
||||||
|
|
||||||
/*
|
//
|
||||||
* SamrOemChangePasswordUser2 api support
|
/* SamrOemChangePasswordUser2 api support */
|
||||||
*/
|
//
|
||||||
#define REMSmb_SamOEMChgPasswordUser2 "B516B16" /* data that is passed */
|
#define REMSmb_SamOEMChgPasswordUser2 "B516B16" /* data that is passed */
|
||||||
|
|
||||||
#endif /* ndef _REMDEF_ */
|
#endif /* ndef _REMDEF_ */
|
||||||
|
|
|
@ -16,7 +16,7 @@ thdr(Session *s, Share *sp)
|
||||||
p->tbase = pl16(p, 0); /* 0 Total parameter bytes to be sent, filled later */
|
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, 0); /* 2 Total data bytes to be sent, filled later */
|
||||||
pl16(p, 64); /* 4 Max parameter to return */
|
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, 1); /* 8 Max setup count to return */
|
||||||
pl16(p, 0); /* 10 Flags */
|
pl16(p, 0); /* 10 Flags */
|
||||||
pl32(p, 1000); /* 12 Timeout (ms) */
|
pl32(p, 1000); /* 12 Timeout (ms) */
|
||||||
|
@ -126,7 +126,7 @@ RAPshareenum(Session *s, Share *sp, Share **ent)
|
||||||
pascii(p, REMSmb_NetShareEnum_P); /* request descriptor */
|
pascii(p, REMSmb_NetShareEnum_P); /* request descriptor */
|
||||||
pascii(p, REMSmb_share_info_0); /* reply descriptor */
|
pascii(p, REMSmb_share_info_0); /* reply descriptor */
|
||||||
pl16(p, 0); /* detail level */
|
pl16(p, 0); /* detail level */
|
||||||
pl16(p, MTU - 200); /* receive buffer length */
|
pl16(p, s->mtu - 1024); /* receive buffer length */
|
||||||
ptdata(p);
|
ptdata(p);
|
||||||
|
|
||||||
if(trpc(p) == -1){
|
if(trpc(p) == -1){
|
||||||
|
@ -183,7 +183,7 @@ RAPshareinfo(Session *s, Share *sp, char *share, Shareinfo2 *si2p)
|
||||||
pascii(p, REMSmb_share_info_2); /* reply descriptor */
|
pascii(p, REMSmb_share_info_2); /* reply descriptor */
|
||||||
pascii(p, share);
|
pascii(p, share);
|
||||||
pl16(p, 1); /* detail level */
|
pl16(p, 1); /* detail level */
|
||||||
pl16(p, MTU - 200); /* receive buffer length */
|
pl16(p, s->mtu - 1024); /* receive buffer length */
|
||||||
|
|
||||||
ptdata(p);
|
ptdata(p);
|
||||||
|
|
||||||
|
@ -252,7 +252,7 @@ RAPsessionenum(Session *s, Share *sp, Sessinfo **sip)
|
||||||
pascii(p, REMSmb_NetSessionEnum_P); /* request descriptor */
|
pascii(p, REMSmb_NetSessionEnum_P); /* request descriptor */
|
||||||
pascii(p, REMSmb_session_info_10); /* reply descriptor */
|
pascii(p, REMSmb_session_info_10); /* reply descriptor */
|
||||||
pl16(p, 10); /* detail level */
|
pl16(p, 10); /* detail level */
|
||||||
pl16(p, MTU - 200); /* receive buffer length */
|
pl16(p, s->mtu - 1024); /* receive buffer length */
|
||||||
ptdata(p);
|
ptdata(p);
|
||||||
|
|
||||||
if(trpc(p) == -1){
|
if(trpc(p) == -1){
|
||||||
|
@ -312,7 +312,7 @@ RAPgroupenum(Session *s, Share *sp, Namelist **nlp)
|
||||||
pascii(p, REMSmb_NetGroupEnum_P); /* request descriptor */
|
pascii(p, REMSmb_NetGroupEnum_P); /* request descriptor */
|
||||||
pascii(p, REMSmb_group_info_0); /* reply descriptor */
|
pascii(p, REMSmb_group_info_0); /* reply descriptor */
|
||||||
pl16(p, 0); /* detail level */
|
pl16(p, 0); /* detail level */
|
||||||
pl16(p, MTU - 200); /* receive buffer length */
|
pl16(p, s->mtu - 1024); /* receive buffer length */
|
||||||
ptdata(p);
|
ptdata(p);
|
||||||
|
|
||||||
if(trpc(p) == -1){
|
if(trpc(p) == -1){
|
||||||
|
@ -368,7 +368,7 @@ RAPgroupusers(Session *s, Share *sp, char *group, Namelist **nlp)
|
||||||
pascii(p, REMSmb_user_info_0); /* reply descriptor */
|
pascii(p, REMSmb_user_info_0); /* reply descriptor */
|
||||||
pascii(p, group); /* group name for list */
|
pascii(p, group); /* group name for list */
|
||||||
pl16(p, 0); /* detail level */
|
pl16(p, 0); /* detail level */
|
||||||
pl16(p, MTU - 200); /* receive buffer length */
|
pl16(p, s->mtu - 1024); /* receive buffer length */
|
||||||
ptdata(p);
|
ptdata(p);
|
||||||
|
|
||||||
if(trpc(p) == -1){
|
if(trpc(p) == -1){
|
||||||
|
@ -422,7 +422,7 @@ RAPuserenum(Session *s, Share *sp, Namelist **nlp)
|
||||||
pascii(p, REMSmb_NetUserEnum_P); /* request descriptor */
|
pascii(p, REMSmb_NetUserEnum_P); /* request descriptor */
|
||||||
pascii(p, REMSmb_user_info_0); /* reply descriptor */
|
pascii(p, REMSmb_user_info_0); /* reply descriptor */
|
||||||
pl16(p, 0); /* detail level */
|
pl16(p, 0); /* detail level */
|
||||||
pl16(p, MTU - 200); /* receive buffer length */
|
pl16(p, s->mtu - 1024); /* receive buffer length */
|
||||||
ptdata(p);
|
ptdata(p);
|
||||||
|
|
||||||
if(trpc(p) == -1){
|
if(trpc(p) == -1){
|
||||||
|
@ -478,7 +478,7 @@ more:
|
||||||
pascii(p, REMSmb_NetUserEnum2_P); /* request descriptor */
|
pascii(p, REMSmb_NetUserEnum2_P); /* request descriptor */
|
||||||
pascii(p, REMSmb_user_info_0); /* reply descriptor */
|
pascii(p, REMSmb_user_info_0); /* reply descriptor */
|
||||||
pl16(p, 0); /* detail level */
|
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 */
|
pl32(p, resume); /* resume key to allow multiple fetches */
|
||||||
ptdata(p);
|
ptdata(p);
|
||||||
|
|
||||||
|
@ -536,7 +536,7 @@ RAPuserinfo(Session *s, Share *sp, char *user, Userinfo *uip)
|
||||||
pascii(p, REMSmb_user_info_10); /* reply descriptor */
|
pascii(p, REMSmb_user_info_10); /* reply descriptor */
|
||||||
pascii(p, user); /* username */
|
pascii(p, user); /* username */
|
||||||
pl16(p, 10); /* detail level */
|
pl16(p, 10); /* detail level */
|
||||||
pl16(p, MTU - 200); /* receive buffer length */
|
pl16(p, s->mtu - 1024); /* receive buffer length */
|
||||||
ptdata(p);
|
ptdata(p);
|
||||||
|
|
||||||
if(trpc(p) == -1){
|
if(trpc(p) == -1){
|
||||||
|
@ -592,7 +592,7 @@ RAPServerenum2(Session *s, Share *sp, char *workgroup, int type, int *more,
|
||||||
pascii(p, REMSmb_NetServerEnum2_P); /* request descriptor */
|
pascii(p, REMSmb_NetServerEnum2_P); /* request descriptor */
|
||||||
pascii(p, REMSmb_server_info_1); /* reply descriptor */
|
pascii(p, REMSmb_server_info_1); /* reply descriptor */
|
||||||
pl16(p, 1); /* detail level */
|
pl16(p, 1); /* detail level */
|
||||||
pl16(p, MTU - 200); /* receive buffer length */
|
pl16(p, s->mtu - 1024); /* receive buffer length */
|
||||||
pl32(p, type);
|
pl32(p, type);
|
||||||
pascii(p, workgroup);
|
pascii(p, workgroup);
|
||||||
|
|
||||||
|
@ -655,7 +655,7 @@ more:
|
||||||
pascii(p, REMSmb_NetServerEnum3_P); /* request descriptor */
|
pascii(p, REMSmb_NetServerEnum3_P); /* request descriptor */
|
||||||
pascii(p, REMSmb_server_info_1); /* reply descriptor */
|
pascii(p, REMSmb_server_info_1); /* reply descriptor */
|
||||||
pl16(p, 1); /* detail level */
|
pl16(p, 1); /* detail level */
|
||||||
pl16(p, MTU - 200); /* receive buffer length */
|
pl16(p, s->mtu - 1024); /* receive buffer length */
|
||||||
pl32(p, type);
|
pl32(p, type);
|
||||||
pascii(p, workgroup);
|
pascii(p, workgroup);
|
||||||
pascii(p, first);
|
pascii(p, first);
|
||||||
|
@ -731,7 +731,7 @@ more:
|
||||||
pascii(p, path);
|
pascii(p, path);
|
||||||
pascii(p, user);
|
pascii(p, user);
|
||||||
pl16(p, 1); /* detail level */
|
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 */
|
pl32(p, resume); /* resume key */
|
||||||
/* FIXME: maybe the padding and resume key are the wrong way around? */
|
/* FIXME: maybe the padding and resume key are the wrong way around? */
|
||||||
pl32(p, 0); /* padding ? */
|
pl32(p, 0); /* padding ? */
|
||||||
|
|
|
@ -15,7 +15,7 @@ t2hdr(Session *s, Share *sp, int cmd)
|
||||||
p->tbase = pl16(p, 0); /* 0 Total parameter bytes to be sent, filled later */
|
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, 0); /* 2 Total data bytes to be sent, filled later */
|
||||||
pl16(p, 64); /* 4 Max parameter to return */
|
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); /* 8 Max setup count to return */
|
||||||
p8(p, 0); /* 9 Reserved */
|
p8(p, 0); /* 9 Reserved */
|
||||||
pl16(p, 0); /* 10 Flags */
|
pl16(p, 0); /* 10 Flags */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue