int authRead(Fid* afid, void* data, int count) { AuthInfo *ai; AuthRpc *rpc; if((rpc = afid->rpc) == nil){ werrstr("not an auth fid"); return -1; } switch(auth_rpc(rpc, "read", nil, 0)){ default: werrstr("fossil authRead: auth protocol not finished"); return -1; case ARdone: if((ai = auth_getinfo(rpc)) == nil){ werrstr("%r"); break; } if(ai->cuid == nil || *ai->cuid == '\0'){ werrstr("auth with no cuid"); auth_freeAI(ai); break; } assert(afid->cuname == nil); afid->cuname = vtstrdup(ai->cuid); auth_freeAI(ai); if(Dflag) fprint(2, "authRead cuname %s\n", afid->cuname); assert(afid->uid == nil); if((afid->uid = uidByUname(afid->cuname)) == nil){ werrstr("unknown user %#q", afid->cuname); break; } return 0; case ARok: if(count < rpc->narg){ werrstr("not enough data in auth read"); break; } memmove(data, rpc->arg, rpc->narg); return rpc->narg; case ARphase: werrstr("%r"); break; } return -1; }
CFsys* fsamount(int fd, char *aname) { CFid *afid, *fid; AuthInfo *ai; CFsys *fs; fs = fsinit(fd); if(fs == nil) return nil; if((afid = fsauth(fs, getuser(), aname)) == nil) goto noauth; ai = fsauth_proxy(afid, amount_getkey, "proto=p9any role=client"); if(ai != nil) auth_freeAI(ai); noauth: fid = fsattach(fs, afid, getuser(), aname); fsclose(afid); if(fid == nil){ _fsunmount(fs); return nil; } fssetroot(fs, fid); return fs; }
static int netkeysrvauth(int fd, char *user) { char response[32]; Chalstate *ch; int tries; AuthInfo *ai; if(readstr(fd, user, 32) < 0) return -1; ai = nil; ch = nil; for(tries = 0; tries < 10; tries++){ if((ch = auth_challenge("proto=p9cr role=server user=%q", user)) == nil) return -1; writestr(fd, ch->chal, "challenge", 1); if(readstr(fd, response, sizeof response) < 0) return -1; ch->resp = response; ch->nresp = strlen(response); if((ai = auth_response(ch)) != nil) break; } auth_freechal(ch); if(ai == nil) return -1; writestr(fd, "", "challenge", 1); if(auth_chuid(ai, 0) < 0) fatal(1, "newns"); auth_freeAI(ai); return fd; }
int vncsrvauth(Vnc *v) { Chalstate *c; AuthInfo *ai; if((c = auth_challenge("proto=vnc role=server user=%q", getuser()))==nil) sysfatal("vncchal: %r"); if(c->nchal != VncChalLen) sysfatal("vncchal got %d bytes wanted %d", c->nchal, VncChalLen); vncwrlong(v, AVncAuth); vncwrbytes(v, c->chal, VncChalLen); vncflush(v); vncrdbytes(v, c->chal, VncChalLen); c->resp = c->chal; c->nresp = VncChalLen; ai = auth_response(c); auth_freechal(c); if(ai == nil){ fprint(2, "vnc auth failed: server factotum: %r\n"); vncwrlong(v, VncAuthFailed); vncflush(v); return -1; } auth_freeAI(ai); vncwrlong(v, VncAuthOK); vncflush(v); return 0; }
static int _authread(Afid *afid, void *data, int count) { AuthInfo *ai; switch(auth_rpc(afid->rpc, "read", nil, 0)){ case ARdone: ai = auth_getinfo(afid->rpc); if(ai == nil) return -1; auth_freeAI(ai); if(chatty9p) fprint(2, "authenticate %s/%s: ok\n", afid->uname, afid->aname); afid->authok = 1; return 0; case ARok: if(count < afid->rpc->narg){ werrstr("authread count too small"); return -1; } count = afid->rpc->narg; memmove(data, afid->rpc->arg, count); return count; case ARphase: default: werrstr("authrpc botch"); return -1; } }
int authread(File *file, uchar *data, int count) { AuthInfo *ai; AuthRpc *rpc; Chan *chan; chan = file->cp; if((rpc = file->auth) == nil){ snprint(chan->err, sizeof(chan->err), "not an auth fid"); return -1; } switch(auth_rpc(rpc, "read", nil, 0)){ default: snprint(chan->err, sizeof(chan->err), "authread: auth protocol not finished"); return -1; case ARdone: if((ai = auth_getinfo(rpc)) == nil) goto Phase; file->uid = strtouid(ai->cuid); if(file->uid < 0){ snprint(chan->err, sizeof(chan->err), "unknown user '%s'", ai->cuid); auth_freeAI(ai); return -1; } auth_freeAI(ai); return 0; case ARok: if(count < rpc->narg){ snprint(chan->err, sizeof(chan->err), "not enough data in auth read"); return -1; } memmove(data, rpc->arg, rpc->narg); return rpc->narg; case ARphase: Phase: rerrstr(chan->err, sizeof(chan->err)); return -1; } }
void checkpassword(void) { int fd, consctl, must; char buf[256]; AuthInfo *ai; static int opened; must = 1; if(!opened){ fd = open("/dev/cons", OREAD); if(fd == -1) error("can't open cons: %r"); dup(fd, 0); close(fd); fd = open("/dev/cons", OWRITE); if(fd == -1) error("can't open cons: %r"); dup(fd, 1); dup(1, 2); close(fd); consctl = open("/dev/consctl", OWRITE); if(consctl == -1) error("can't open consctl: %r"); if(write(consctl, "rawon", 5) != 5) error("can't turn off echo\n"); opened = 1; } for(;;){ if(chatty || !must) fprint(2, "%s's screenlock password: "******"\n"); if(buf[0] == '\0' || buf[0] == '\04'){ if(must) continue; error("no password typed"); } /* authenticate */ ai = auth_userpasswd(user, buf); if(ai != nil && ai->cap != nil) break; auth_freeAI(ai); if(chatty || !must) fprint(2, "password mismatch\n"); doblank = 1; } memset(buf, 0, sizeof buf); blankscreen(0); }
static void authsrvuser(Conn *c) { int i; char *ns, *user; AuthInfo *ai; Msg *m; m = recvmsg(c, SSH_CMSG_USER); user = getstring(m); c->user = emalloc(strlen(user)+1); strcpy(c->user, user); free(m); ai = authusername(c); while(ai == nil){ /* * clumsy: if the client aborted the auth_tis early * we don't send a new failure. we check this by * looking at c->unget, which is only used in that * case. */ if(c->unget != nil) goto skipfailure; sendmsg(allocmsg(c, SSH_SMSG_FAILURE, 0)); skipfailure: m = recvmsg(c, -1); for(i=0; i<c->nokauthsrv; i++) if(c->okauthsrv[i]->firstmsg == m->type){ ai = (*c->okauthsrv[i]->fn)(c, m); break; } if(i==c->nokauthsrv) badmsg(m, 0); } sendmsg(allocmsg(c, SSH_SMSG_SUCCESS, 0)); if(noworld(ai->cuid)) ns = "/lib/namespace.noworld"; else ns = nil; if(auth_chuid(ai, ns) < 0){ sshlog("auth_chuid to %s: %r", ai->cuid); sysfatal("auth_chuid: %r"); } sshlog("logged in as %s", ai->cuid); auth_freeAI(ai); }
int amount(int fd, char *mntpt, int flags, char *aname) { int rv, afd; AuthInfo *ai; afd = fauth(fd, aname); if(afd >= 0){ ai = auth_proxy(afd, amount_getkey, "proto=p9any role=client"); if(ai != nil) auth_freeAI(ai); } rv = mount(fd, afd, mntpt, flags, aname); if(afd >= 0) close(afd); return rv; }
static int famount(int fd, AuthRpc *rpc, char *mntpt, int flags, char *aname) { int afd; AuthInfo *ai; int ret; afd = fauth(fd, aname); if(afd >= 0){ ai = fauth_proxy(afd, rpc, amount_getkey, "proto=p9any role=client"); if(ai != nil) auth_freeAI(ai); } ret = mount(fd, afd, mntpt, flags, aname); if(afd >= 0) close(afd); return ret; }
static int dologin(char *response) { AuthInfo *ai; static int tries; static uint32_t delaysecs = 5; chs->user = user; chs->resp = response; chs->nresp = strlen(response); if((ai = auth_response(chs)) == nil){ if(tries >= 20){ senderr("authentication failed: %r; server exiting"); exits(nil); } if(++tries == 3) syslog(0, "pop3", "likely password guesser from %s", peeraddr); delaysecs *= 2; if (delaysecs > 30*60) delaysecs = 30*60; /* half-hour max. */ sleep(delaysecs * 1000); /* prevent beating on our auth server */ return senderr("authentication failed"); } if(auth_chuid(ai, nil) < 0){ senderr("chuid failed: %r; server exiting"); exits(nil); } auth_freeAI(ai); auth_freechal(chs); chs = nil; loggedin = 1; if(newns(user, 0) < 0){ senderr("newns failed: %r; server exiting"); exits(nil); } syslog(0, "pop3", "user %s logged in", user); enableaddr(); if(readmbox(box) < 0) exits(nil); return sendok("mailbox is %s", box); }
void setupuser(AuthInfo *ai) { Waitmsg *w; int pid; if(ai){ strecpy(username, username+sizeof username, ai->cuid); if(auth_chuid(ai, nil) < 0) bye("user auth failed: %r"); auth_freeAI(ai); }else strecpy(username, username+sizeof username, getuser()); if(newns(username, 0) < 0) bye("user login failed: %r"); /* * hack to allow access to outgoing smtp forwarding */ enableForwarding(); snprint(mboxDir, MboxNameLen, "/mail/box/%s", username); if(myChdir(mboxDir) < 0) bye("can't open user's mailbox"); switch(pid = fork()){ case -1: bye("can't initialize mail system"); break; case 0: execl("/bin/upas/fs", "upas/fs", "-np", nil); _exits("rob1"); _exits(0); break; default: break; } if((w=wait()) == nil || w->pid != pid || w->msg[0] != '\0') bye("can't initialize mail system"); free(w); }
int amount0(int fd, char *mntpt, int flags, char *aname, char *keyspec) { int rv, afd; AuthInfo *ai; afd = fauth(fd, aname); if(afd >= 0){ ai = auth_proxy(afd, amount_getkey, "proto=p9any role=client %s", keyspec); if(ai != nil) auth_freeAI(ai); else fprint(2, "%s: auth_proxy: %r\n", argv0); } rv = mount(fd, afd, mntpt, flags, aname); if(afd >= 0) close(afd); return rv; }
static uchar* convM2AI(uchar *p, int n, AuthInfo **aip) { uchar *e = p+n; AuthInfo *ai; ai = mallocz(sizeof(*ai), 1); if(ai == nil) return nil; p = gstring(p, e, &ai->cuid); p = gstring(p, e, &ai->suid); p = gstring(p, e, &ai->cap); p = gcarray(p, e, &ai->secret, &ai->nsecret); if(p == nil) auth_freeAI(ai); else *aip = ai; return p; }
/* returns 0 if auth succeeded (or unneeded), -1 otherwise */ int authhostowner(Session *s) { Fid *af, *f; int rv = -1; int afd; AuthInfo *ai; AuthRpc *rpc; /* get a fid to authenticate over */ f = nil; af = newfid(s); s->f.afid = af - s->fids; s->f.uname = getuser(); s->f.aname = s->spec; if(xmesg(s, Tauth)){ /* not needed */ rv = 0; goto out; } quotefmtinstall(); /* just in case */ afd = open("/mnt/factotum/rpc", ORDWR); if(afd < 0){ werrstr("opening /mnt/factotum/rpc: %r"); goto out; } rpc = auth_allocrpc(afd); if(rpc == nil) goto out; ai = authproto(s, af, rpc, auth_getkey, "proto=p9any role=client"); if(ai != nil){ rv = 0; auth_freeAI(ai); } auth_freerpc(rpc); close(afd); /* try attaching with the afid */ chat("attaching as hostowner..."); f = newfid(s); s->f.fid = f - s->fids; s->f.afid = af - s->fids;; s->f.uname = getuser(); s->f.aname = s->spec; if(xmesg(s, Tattach) == 0) rv = 0; out: if(af != nil){ putfid(s, af); s->f.fid = af - s->fids; xmesg(s, Tclunk); } if(f != nil){ putfid(s, f); s->f.fid = f - s->fids; xmesg(s, Tclunk); } return rv; }
void main(int argc, char *argv[]) { char pass[ANAMELEN]; char buf[2*ANAMELEN]; char home[2*ANAMELEN]; char srvname[2*ANAMELEN]; char *user, *sysname, *tz, *cputype, *service; AuthInfo *ai; ARGBEGIN{ }ARGEND; rfork(RFENVG|RFNAMEG); service = getenv("service"); if(strcmp(service, "cpu") == 0) fprint(2, "login: warning: running on a cpu server!\n"); if(argc != 1){ fprint(2, "usage: login username\n"); exits("usage"); } user = argv[0]; memset(pass, 0, sizeof(pass)); readln("Password: "******"login incorrect"); /* change uid */ chuid(ai); /* start a new factotum and hand it a new key */ startfactotum(user, pass, srvname); /* set up new namespace */ newns(ai->cuid, nil); auth_freeAI(ai); /* remount the factotum */ mountfactotum(srvname); /* set up a new environment */ cputype = getenv("cputype"); sysname = getenv("sysname"); tz = getenv("timezone"); rfork(RFCENVG); setenv("#e/service", "con"); setenv("#e/user", user); snprint(home, sizeof(home), "/usr/%s", user); setenv("#e/home", home); setenv("#e/cputype", cputype); setenv("#e/objtype", cputype); if(sysname != nil) setenv("#e/sysname", sysname); if(tz != nil) setenv("#e/timezone", tz); /* go to new home directory */ snprint(buf, sizeof(buf), "/usr/%s", user); if(chdir(buf) < 0) chdir("/"); /* read profile and start interactive rc */ execl("/bin/rc", "rc", "-li", nil); exits(0); }
void auth(String *mech, String *resp) { char *user, *pass, *scratch = nil; AuthInfo *ai = nil; Chalstate *chs = nil; String *s_resp1_64 = nil, *s_resp2_64 = nil, *s_resp1 = nil; String *s_resp2 = nil; if (rejectcheck()) goto bomb_out; syslog(0, "smtpd", "auth(%s, %s) from %s", s_to_c(mech), "(protected)", him); if (authenticated) { bad_sequence: rejectcount++; reply("503 5.5.2 Bad sequence of commands\r\n"); goto bomb_out; } if (cistrcmp(s_to_c(mech), "plain") == 0) { if (!passwordinclear) { rejectcount++; reply("538 5.7.1 Encryption required for requested " "authentication mechanism\r\n"); goto bomb_out; } s_resp1_64 = resp; if (s_resp1_64 == nil) { reply("334 \r\n"); s_resp1_64 = s_new(); if (getcrnl(s_resp1_64, &bin) <= 0) goto bad_sequence; } s_resp1 = s_dec64(s_resp1_64); if (s_resp1 == nil) { rejectcount++; reply("501 5.5.4 Cannot decode base64\r\n"); goto bomb_out; } memset(s_to_c(s_resp1_64), 'X', s_len(s_resp1_64)); user = s_to_c(s_resp1) + strlen(s_to_c(s_resp1)) + 1; pass = user + strlen(user) + 1; ai = auth_userpasswd(user, pass); authenticated = ai != nil; memset(pass, 'X', strlen(pass)); goto windup; } else if (cistrcmp(s_to_c(mech), "login") == 0) { if (!passwordinclear) { rejectcount++; reply("538 5.7.1 Encryption required for requested " "authentication mechanism\r\n"); goto bomb_out; } if (resp == nil) { reply("334 VXNlcm5hbWU6\r\n"); s_resp1_64 = s_new(); if (getcrnl(s_resp1_64, &bin) <= 0) goto bad_sequence; } reply("334 UGFzc3dvcmQ6\r\n"); s_resp2_64 = s_new(); if (getcrnl(s_resp2_64, &bin) <= 0) goto bad_sequence; s_resp1 = s_dec64(s_resp1_64); s_resp2 = s_dec64(s_resp2_64); memset(s_to_c(s_resp2_64), 'X', s_len(s_resp2_64)); if (s_resp1 == nil || s_resp2 == nil) { rejectcount++; reply("501 5.5.4 Cannot decode base64\r\n"); goto bomb_out; } ai = auth_userpasswd(s_to_c(s_resp1), s_to_c(s_resp2)); authenticated = ai != nil; memset(s_to_c(s_resp2), 'X', s_len(s_resp2)); windup: if (authenticated) { /* if you authenticated, we trust you despite your IP */ trusted = 1; reply("235 2.0.0 Authentication successful\r\n"); } else { rejectcount++; reply("535 5.7.1 Authentication failed\r\n"); syslog(0, "smtpd", "authentication failed: %r"); } goto bomb_out; } else if (cistrcmp(s_to_c(mech), "cram-md5") == 0) { int chal64n; char *resp, *t; chs = auth_challenge("proto=cram role=server"); if (chs == nil) { rejectcount++; reply("501 5.7.5 Couldn't get CRAM-MD5 challenge\r\n"); goto bomb_out; } scratch = malloc(chs->nchal * 2 + 1); chal64n = enc64(scratch, chs->nchal * 2, (uchar *)chs->chal, chs->nchal); scratch[chal64n] = 0; reply("334 %s\r\n", scratch); s_resp1_64 = s_new(); if (getcrnl(s_resp1_64, &bin) <= 0) goto bad_sequence; s_resp1 = s_dec64(s_resp1_64); if (s_resp1 == nil) { rejectcount++; reply("501 5.5.4 Cannot decode base64\r\n"); goto bomb_out; } /* should be of form <user><space><response> */ resp = s_to_c(s_resp1); t = strchr(resp, ' '); if (t == nil) { rejectcount++; reply("501 5.5.4 Poorly formed CRAM-MD5 response\r\n"); goto bomb_out; } *t++ = 0; chs->user = resp; chs->resp = t; chs->nresp = strlen(t); ai = auth_response(chs); authenticated = ai != nil; goto windup; } rejectcount++; reply("501 5.5.1 Unrecognised authentication type %s\r\n", s_to_c(mech)); bomb_out: if (ai) auth_freeAI(ai); if (chs) auth_freechal(chs); if (scratch) free(scratch); if (s_resp1) s_free(s_resp1); if (s_resp2) s_free(s_resp2); if (s_resp1_64) s_free(s_resp1_64); if (s_resp2_64) s_free(s_resp2_64); }
void main(int argc, char **argv) { char *mntpt, *srvpost, srvfile[64]; int backwards = 0, fd, mntflags, oldserver; quotefmtinstall(); srvpost = nil; oldserver = 0; mntflags = MREPL; ARGBEGIN{ case 'A': doauth = 0; break; case 'a': mntflags = MAFTER; break; case 'b': mntflags = MBEFORE; break; case 'c': mntflags |= MCREATE; break; case 'C': mntflags |= MCACHE; break; case 'd': debug++; break; case 'f': /* ignored but allowed for compatibility */ break; case 'O': case 'o': oldserver = 1; break; case 'E': if ((encproto = lookup(EARGF(usage()), encprotos)) < 0) usage(); break; case 'e': ealgs = EARGF(usage()); if(*ealgs == 0 || strcmp(ealgs, "clear") == 0) ealgs = nil; break; case 'k': keyspec = EARGF(usage()); break; case 'p': filterp = aan; break; case 'n': anstring = EARGF(usage()); break; case 's': srvpost = EARGF(usage()); break; case 'B': backwards = 1; break; case 'z': skiptree = 1; break; default: usage(); }ARGEND; mntpt = 0; /* to shut up compiler */ if(backwards){ switch(argc) { default: mntpt = argv[0]; break; case 0: usage(); } } else { switch(argc) { case 2: mntpt = argv[1]; break; case 3: mntpt = argv[2]; break; default: usage(); } } if (encproto == Enctls) sysfatal("%s: tls has not yet been implemented", argv[0]); notify(catcher); alarm(60*1000); if (backwards) fd = passive(); else fd = connect(argv[0], argv[1], oldserver); if (!oldserver) fprint(fd, "impo %s %s\n", filterp? "aan": "nofilter", encprotos[encproto]); if (encproto != Encnone && ealgs && ai) { uchar key[16], digest[SHA1dlen]; char fromclientsecret[21]; char fromserversecret[21]; int i; assert(ai->nsecret <= sizeof(key)-4); memmove(key+4, ai->secret, ai->nsecret); /* exchange random numbers */ srand(truerand()); for(i = 0; i < 4; i++) key[i] = rand(); if(write(fd, key, 4) != 4) sysfatal("can't write key part: %r"); if(readn(fd, key+12, 4) != 4) sysfatal("can't read key part: %r"); /* scramble into two secrets */ sha1(key, sizeof(key), digest, nil); mksecret(fromclientsecret, digest); mksecret(fromserversecret, digest+10); if (filterp) fd = filter(fd, filterp, backwards ? nil : argv[0]); /* set up encryption */ procsetname("pushssl"); fd = pushssl(fd, ealgs, fromclientsecret, fromserversecret, nil); if(fd < 0) sysfatal("can't establish ssl connection: %r"); } else if (filterp) fd = filter(fd, filterp, backwards ? nil : argv[0]); if(ai) auth_freeAI(ai); if(srvpost){ snprint(srvfile, sizeof(srvfile), "/srv/%s", srvpost); remove(srvfile); post(srvfile, srvpost, fd); } procsetname("mount on %s", mntpt); if(mount(fd, -1, mntpt, mntflags, "") < 0) sysfatal("can't mount %s: %r", argv[1]); alarm(0); if(backwards && argc > 1){ exec(argv[1], &argv[1]); sysfatal("exec: %r"); } exits(0); }
SmbProcessResult smbcomsessionsetupandx(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b) { uchar andxcommand; ushort andxoffset; ulong andxfixupoffset; ushort vcnumber; ulong sessionkey; ushort caseinsensitivepasswordlength; ushort casesensitivepasswordlength; ushort bytecountfixup, offset; uchar *mschapreply; AuthInfo *ai; char *sp; SmbProcessResult pr; char *accountname = nil; char *primarydomain = nil; char *nativeos = nil; char *nativelanman = nil; if (!smbcheckwordcount("comsessionsetupandx", h, 13)) { fmtfail: pr = SmbProcessResultFormat; goto done; } andxcommand = *pdata++; switch (andxcommand) { case SMB_COM_TREE_CONNECT_ANDX: case SMB_COM_OPEN_ANDX: case SMB_COM_CREATE_NEW: case SMB_COM_DELETE: case SMB_COM_FIND: case SMB_COM_COPY: case SMB_COM_NT_RENAME: case SMB_COM_QUERY_INFORMATION: case SMB_COM_NO_ANDX_COMMAND: case SMB_COM_OPEN: case SMB_COM_CREATE: case SMB_COM_CREATE_DIRECTORY: case SMB_COM_DELETE_DIRECTORY: case SMB_COM_FIND_UNIQUE: case SMB_COM_RENAME: case SMB_COM_CHECK_DIRECTORY: case SMB_COM_SET_INFORMATION: case SMB_COM_OPEN_PRINT_FILE: break; default: smblogprint(h->command, "smbcomsessionsetupandx: invalid andxcommand %s (0x%.2ux)\n", smboptable[andxcommand].name, andxcommand); goto fmtfail; } pdata++; andxoffset = smbnhgets(pdata); pdata += 2; s->peerinfo.maxlen = smbnhgets(pdata); pdata += 2; smbresponseinit(s, s->peerinfo.maxlen); s->client.maxmpxcount = smbnhgets(pdata); pdata += 2; vcnumber = smbnhgets(pdata); pdata += 2; sessionkey = smbnhgetl(pdata); pdata += 4; caseinsensitivepasswordlength = smbnhgets(pdata); pdata += 2; casesensitivepasswordlength = smbnhgets(pdata); pdata += 2; pdata += 4; s->peerinfo.capabilities = smbnhgetl(pdata); /*pdata += 4;*/ smbloglock(); smblogprint(h->command, "andxcommand: %s offset %ud\n", smboptable[andxcommand].name, andxoffset); smblogprint(h->command, "client.maxbuffersize: %ud\n", s->peerinfo.maxlen); smblogprint(h->command, "client.maxmpxcount: %ud\n", s->client.maxmpxcount); smblogprint(h->command, "vcnumber: %ud\n", vcnumber); smblogprint(h->command, "sessionkey: 0x%.8lux\n", sessionkey); smblogprint(h->command, "caseinsensitivepasswordlength: %ud\n", caseinsensitivepasswordlength); smblogprint(h->command, "casesensitivepasswordlength: %ud\n", casesensitivepasswordlength); smblogprint(h->command, "clientcapabilities: 0x%.8lux\n", s->peerinfo.capabilities); smblogunlock(); mschapreply = smbbufferreadpointer(b); if (!smbbuffergetbytes(b, nil, caseinsensitivepasswordlength + casesensitivepasswordlength)) { smblogprint(h->command, "smbcomsessionsetupandx: not enough bdata for passwords\n"); goto fmtfail; } if (!smbbuffergetstring(b, h, 0, &accountname) || !smbbuffergetstring(b, h, 0, &primarydomain) || !smbbuffergetstring(b, h, 0, &nativeos) || !smbbuffergetstring(b, h, 0, &nativelanman)) { smblogprint(h->command, "smbcomsessionsetupandx: not enough bytes for strings\n"); goto fmtfail; } for (sp = accountname; *sp; sp++) *sp = tolower(*sp); smblogprint(h->command, "account: %s\n", accountname); smblogprint(h->command, "primarydomain: %s\n", primarydomain); smblogprint(h->command, "nativeos: %s\n", nativeos); smblogprint(h->command, "nativelanman: %s\n", nativelanman); if (s->client.accountname && accountname[0] && strcmp(s->client.accountname, accountname) != 0) { smblogprint(h->command, "smbcomsessionsetupandx: more than one user on VC (before %s, now %s)\n", s->client.accountname, accountname); smbseterror(s, ERRSRV, ERRtoomanyuids); errordone: pr = SmbProcessResultError; goto done; } if (s->client.accountname == nil) { /* first time */ if (accountname[0] == 0) { smbseterror(s, ERRSRV, ERRbaduid); goto errordone; } if ((casesensitivepasswordlength != 24 || caseinsensitivepasswordlength != 24)) { smblogprint(h->command, "smbcomsessionsetupandx: case sensitive/insensitive password length not 24\n"); smbseterror(s, ERRSRV, ERRbadpw); goto errordone; } memcpy(&s->client.mschapreply, mschapreply, sizeof(s->client.mschapreply)); if(s->cs == nil){ smbseterror(s, ERRSRV, ERRerror); goto errordone; } s->cs->user = accountname; s->cs->resp = &s->client.mschapreply; s->cs->nresp = sizeof(MSchapreply); ai = auth_response(s->cs); if (ai == nil) { smblogprint(h->command, "authentication failed\n"); smbseterror(s, ERRSRV, ERRbadpw); goto errordone; } smblogprint(h->command, "authentication succeeded\n"); if (auth_chuid(ai, nil) < 0) { smblogprint(h->command, "smbcomsessionsetupandx: chuid failed: %r\n"); auth_freeAI(ai); miscerror: pr = SmbProcessResultMisc; goto done; } auth_freeAI(ai); h->uid = 1; s->client.accountname = accountname; s->client.primarydomain = primarydomain; s->client.nativeos = nativeos; s->client.nativelanman = nativelanman; accountname = nil; primarydomain = nil; nativeos = nil; nativelanman = nil; } else { if (caseinsensitivepasswordlength == 24 && casesensitivepasswordlength == 24 && memcmp(&s->client.mschapreply, mschapreply, sizeof(MSchapreply)) != 0) { smblogprint(h->command, "second time authentication failed\n"); smbseterror(s, ERRSRV, ERRbadpw); goto errordone; } } /* CIFS says 4 with or without extended security, samba/ms says 3 without */ h->wordcount = 3; if (!smbresponseputandxheader(s, h, andxcommand, &andxfixupoffset)) goto miscerror; if (!smbresponseputs(s, 0)) goto miscerror; bytecountfixup = smbresponseoffset(s); if (!smbresponseputs(s, 0)) goto miscerror; if (!smbresponseputstring(s, 1, smbglobals.nativeos) || !smbresponseputstring(s, 1, smbglobals.serverinfo.nativelanman) || !smbresponseputstring(s, 1, smbglobals.primarydomain)) goto miscerror; offset = smbresponseoffset(s); smbresponseoffsetputs(s, bytecountfixup, offset - bytecountfixup - 2); s->state = SmbSessionEstablished; if (andxcommand != SMB_COM_NO_ANDX_COMMAND) pr = smbchaincommand(s, h, andxfixupoffset, andxcommand, andxoffset, b); else pr = SmbProcessResultReply; done: free(accountname); free(primarydomain); free(nativeos); free(nativelanman); return pr; }