cifs: updated cifs/smb client to quintiles latest version

This commit is contained in:
cinap_lenrek 2012-01-16 18:42:16 +01:00
parent b15accceac
commit 8f5375fa61
13 changed files with 388 additions and 341 deletions

View file

@ -20,6 +20,9 @@ cifs - Microsoft™ Windows network filesystem client
] [
.B -m
.I mntpnt
] [
.B -t
.I dfs-timeout
]
.I host
[
@ -32,8 +35,7 @@ translates between Microsoft's file-sharing protocol
(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 @@ CIFS packet debug.
.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 @@ and finally it will try the name
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 @@ Several synthetic files appear in the root of the mounted filesystem:
.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 @@ the version number of the OS it is running, and comma-separated list of flags
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.
.PP
Kerberos authentication is unfinished.
Kerberos authentication is not supported.
.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.

View file

@ -137,30 +137,28 @@ hmac_t64(uchar *data, ulong dlen, uchar *key, ulong klen, uchar *digest,
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;
@ -172,18 +170,19 @@ ntv2_blob(uchar *blob, int len, char *windom)
*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 @@ ntv2_blob(uchar *blob, int len, char *windom)
*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;
*p++ = Beof; /* name type */
*p++ = 0;
*p++ = 0; /* name length */
*p++ = 0x65;
*p++ = 0; /* 32bit: unknown data */
*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;
}

View file

@ -135,77 +135,80 @@ hmac_t64(uchar *data, ulong dlen, uchar *key, ulong klen, uchar *digest,
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;
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) */
};
uchar *p = buf;
p = blob;
*p++ = 1; /* response type */
*p++ = 1; /* max response type understood by client */
*p++ = type;
*p++ = 0; /* 16bit: name type */
*p++ = 0;
*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;
n = utflen(name) * 2;
*p++ = n;
*p++ = n >> 8; /* name length */
*p++ = n >> 8; /* 16bit: name length */
d = windom;
while(*d && p-blob < (len-8)){
d = name;
while(*d != 0 && p-buf < len-8){
d += chartorune(&r, d);
r = toupperrune(r);
*p++ = r;
*p++ = r >> 8;
}
*p++ = r >> 8;
} /* var: actual name */
*p++ = 0;
*p++ = Beof; /* name type */
return p - buf;
}
*p++ = 0;
*p++ = 0; /* name length */
static int
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; /* 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;
}
@ -293,7 +296,7 @@ auth_ntlmv2(char *windom, char *keyp, uchar *chal, int len)
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;

View file

@ -40,8 +40,12 @@ cifsdial(char *host, char *called, char *sysname)
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 @@ cifshdr(Session *s, Share *sp, int cmd)
p->buf = (uchar *)p + sizeof(Pkt);
p->s = s;
p->request = cmd; /* for debug */
qlock(&s->seqlock);
if(s->seqrun){
@ -137,11 +142,12 @@ dmp(int seq, uchar *buf)
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 @@ cifsrpc(Pkt *p)
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 @@ cifsrpc(Pkt *p)
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 @@ print("MAC signature bad\n");
* 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 @@ print("MAC signature bad\n");
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 @@ CIFSnegotiate(Session *s, long *svrtime, char *domain, int domlen, char *cname,
};
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 @@ CIFSnegotiate(Session *s, long *svrtime, char *domain, int domlen, char *cname,
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 @@ CIFSsession(Session *s)
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 @@ CIFStreeconnect(Session *s, char *cname, char *tree, Share *sp)
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 @@ CIFStreeconnect(Session *s, char *cname, char *tree, Share *sp)
}
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);

View file

@ -350,10 +350,10 @@ typedef struct {
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 @@ typedef struct {
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 Ipc;
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);
/* 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 **);
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 */
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);

View file

@ -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 @@ dirgeninfo(int slot, Dir *d)
d->qid.vers = 1;
d->qid.path = slot;
d->qid.type = 0;
return 0;
}
@ -76,10 +77,12 @@ makeinfo(int path)
if(Infdir[path].buf != nil)
return 0;
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;
Infdir[path].buf = fmtstrflush(&f);
Infdir[path].len = strlen(Infdir[path].buf);
return 0;
}
@ -104,3 +107,4 @@ freeinfo(int path)
free(Infdir[path].buf);
Infdir[path].buf = nil;
}

View file

@ -198,7 +198,9 @@ dirgen(int slot, Dir *d, void *aux)
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){
@ -1103,6 +1105,7 @@ keepalive(void)
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 @@ connected:
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 @@ connected:
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;
}

View file

@ -11,10 +11,3 @@ OFILES= main.$O transnt.$O trans2.$O trans.$O cifs.$O \
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

View file

@ -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 @@ static struct {
{ "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 @@ static struct {
{ "SXS multiple deactivation", 0xc0150011 },
{ "SXS system default activation context empty",0xc0150012 },
{ "SXS process termination requested", 0xc0150013 },
};
};
char *
nterrstr(uint err)
@ -1006,14 +1006,13 @@ nterrstr(uint err)
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;
}

View file

@ -27,7 +27,7 @@ ppath(Pkt *p, char *str)
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 @@ pstr(Pkt *p, char *str)
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 @@ gstr(Pkt *p, char *str, int n)
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);

View file

@ -48,11 +48,11 @@ Revision History:
#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 @@ Revision History:
#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 @@ Revision History:
#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_ */

View file

@ -16,7 +16,7 @@ thdr(Session *s, Share *sp)
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 @@ RAPshareenum(Session *s, Share *sp, Share **ent)
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 @@ RAPshareinfo(Session *s, Share *sp, char *share, Shareinfo2 *si2p)
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 @@ RAPsessionenum(Session *s, Share *sp, Sessinfo **sip)
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 @@ RAPgroupenum(Session *s, Share *sp, Namelist **nlp)
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 @@ RAPgroupusers(Session *s, Share *sp, char *group, Namelist **nlp)
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 @@ RAPuserenum(Session *s, Share *sp, Namelist **nlp)
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 @@ more:
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 @@ RAPuserinfo(Session *s, Share *sp, char *user, Userinfo *uip)
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 @@ RAPServerenum2(Session *s, Share *sp, char *workgroup, int type, int *more,
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 @@ more:
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 @@ more:
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 ? */

View file

@ -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 */
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 */