|
|
|
2001/0503/sys/src/9/port/auth.c:5,40 –
2001/0527/sys/src/9/port/auth.c:5,13
(short | long | prev | next)
|
|
1993/0330
| |
#include "fns.h"
#include "../port/error.h"
typedef struct Crypt Crypt;
struct Crypt
{
Crypt *next;
Ticket t;
Authenticator a;
char tbuf[TICKETLEN]; /* remote ticket */
};
|
|
2001/0527
| |
#include <auth.h>
|
|
1993/0330
| |
|
|
1993/0731
| |
typedef struct Session Session;
|
|
1993/0330
| |
struct Session
{
Lock;
|
|
1993/0731
| |
Lock send;
|
|
1993/0330
| |
Crypt *cache; /* cache of tickets */
char cchal[CHALLEN]; /* client challenge */
char schal[CHALLEN]; /* server challenge */
char authid[NAMELEN]; /* server encryption uid */
char authdom[DOMLEN]; /* server encryption domain */
ulong cid; /* challenge id */
|
|
1993/0731
| |
int valid;
|
|
1993/0330
| |
};
struct
{
Lock;
Crypt *free;
} cryptalloc;
|
|
1994/1027
| |
char eve[NAMELEN];
|
|
2001/0527
| |
char *eve;
|
|
1993/0330
| |
char evekey[DESKEYLEN];
char hostdomain[DOMLEN];
|
|
2001/0503/sys/src/9/port/auth.c:47,573 –
2001/0527/sys/src/9/port/auth.c:20,204
|
|
1993/0501
| |
return strcmp(eve, up->user) == 0;
|
|
1993/0330
| |
}
/*
* crypt entries are allocated from a pool rather than allocated using malloc so
* the memory can be protected from reading by devproc. The base and top of the
* crypt arena is stored in palloc for devproc.
*/
Crypt*
newcrypt(void)
{
Crypt *c;
lock(&cryptalloc);
if(cryptalloc.free) {
c = cryptalloc.free;
cryptalloc.free = c->next;
unlock(&cryptalloc);
memset(c, 0, sizeof(Crypt));
return c;
}
cryptalloc.free = xalloc(sizeof(Crypt)*conf.nproc);
if(cryptalloc.free == 0)
panic("newcrypt");
for(c = cryptalloc.free; c < cryptalloc.free+conf.nproc-1; c++)
c->next = c+1;
palloc.cmembase = (ulong)cryptalloc.free;
palloc.cmemtop = palloc.cmembase+(sizeof(Crypt)*conf.nproc);
unlock(&cryptalloc);
return newcrypt();
}
void
freecrypt(Crypt *c)
{
lock(&cryptalloc);
c->next = cryptalloc.free;
cryptalloc.free = c;
unlock(&cryptalloc);
}
/*
* return the info received in the session message on this channel.
* if no session message has been exchanged, do it.
*/
long
sysfsession(ulong *arg)
|
|
2001/0527
| |
sysfversion(ulong *arg)
|
|
1993/0330
| |
{
int i, n;
|
|
2001/0527
| |
Fcall f; /* two Fcalls should be big enough for reply */
uchar *msg;
char *vers;
uint arglen, n, m, msize;
|
|
1993/0330
| |
Chan *c;
Crypt *cp;
Session *s;
Ticketreq tr;
|
|
1993/0407
| |
Fcall f;
char buf[MAXMSG];
|
|
2001/0527
| |
uvlong oo;
|
|
1993/0330
| |
validaddr(arg[1], TICKREQLEN, 1);
c = fdtochan(arg[0], OWRITE, 0, 1);
|
|
2001/0527
| |
msize = arg[1];
vers = (char*)arg[2];
arglen = arg[3];
validaddr(arg[2], arglen, 1);
/* check there's a NUL in the version string */
if(memchr(vers, 0, arglen) == 0)
error(Ebadarg);
c = fdtochan(arg[0], ORDWR, 0, 1);
|
|
1993/0407
| |
if(waserror()){
|
|
1997/0327
| |
cclose(c);
|
|
1993/0330
| |
nexterror();
}
|
|
1993/0407
| |
|
|
1993/0731
| |
/* add a session structure to the channel if it has none */
lock(c);
|
|
1993/0330
| |
s = c->session;
if(s == 0){
s = malloc(sizeof(Session));
|
|
1993/0731
| |
if(s == 0){
unlock(c);
|
|
1993/0330
| |
error(Enomem);
|
|
1993/0731
| |
}
c->session = s;
|
|
2001/0527
| |
if((c->flag&CMSG) && c->version!=nil) /* BUG: insufficient; should check compatibility */
goto Return;
f.type = Tversion;
f.tag = NOTAG;
if(msize == 0)
msize = IOHDRSZ+8192; /* reasonable default */
f.msize = msize;
if(vers[0] == '\0')
vers = VERSION9P;
f.version = vers;
msg = smalloc(MAXMSG);
if(waserror()){
free(msg);
nexterror();
|
|
1993/0731
| |
}
|
|
2001/0527
| |
n = convS2M(&f, msg, MAXMSG);
if(n == 0)
error("bad fversion conversion on send");
lock(c);
oo = c->offset;
c->offset += n;
|
|
1993/0731
| |
unlock(c);
|
|
1993/0407
| |
|
|
1993/0731
| |
/* back off if someone else is doing an fsession */
|
|
1995/0110
| |
while(!canlock(&s->send))
|
|
1993/0731
| |
sched();
|
|
2001/0527
| |
m = devtab[c->type]->write(c, msg, n, oo);
|
|
1993/0731
| |
|
|
1995/0414
| |
if(s->valid == 0 && (c->flag & CMSG) == 0){
|
|
1993/0407
| |
/*
* Exchange a session message with the server.
* If an error occurs reading or writing,
* assume this is a mount of a mount and turn off
* authentication.
*/
if(!waserror()){
for(i = 0; i < CHALLEN; i++)
s->cchal[i] = nrand(256);
f.tag = NOTAG;
f.type = Tsession;
memmove(f.chal, s->cchal, CHALLEN);
n = convS2M(&f, buf);
|
|
1997/0327
| |
if(devtab[c->type]->write(c, buf, n, 0) != n)
|
|
1993/0407
| |
error(Emountrpc);
|
|
1997/0327
| |
n = devtab[c->type]->read(c, buf, sizeof buf, 0);
|
|
1993/0407
| |
if(n == 2 && buf[0] == 'O' && buf[1] == 'K')
|
|
1997/0327
| |
n = devtab[c->type]->read(c, buf, sizeof buf, 0);
|
|
1993/0407
| |
poperror();
if(convM2S(buf, &f, n) == 0){
|
|
1993/0731
| |
unlock(&s->send);
|
|
1993/0407
| |
error(Emountrpc);
}
switch(f.type){
case Rsession:
memmove(s->schal, f.chal, CHALLEN);
memmove(s->authid, f.authid, NAMELEN);
memmove(s->authdom, f.authdom, DOMLEN);
break;
case Rerror:
|
|
1993/0731
| |
unlock(&s->send);
|
|
1993/0407
| |
error(f.ename);
default:
|
|
1993/0731
| |
unlock(&s->send);
|
|
1993/0407
| |
error(Emountrpc);
}
|
|
1993/0330
| |
}
|
|
1993/0731
| |
s->valid = 1;
|
|
2001/0527
| |
if(m < n){
lock(c);
c->offset -= n - m;
unlock(c);
error("short write in fversion");
|
|
1993/0330
| |
}
|
|
1993/0731
| |
unlock(&s->send);
|
|
1993/0330
| |
|
|
1998/0512
| |
/*
|
|
1993/0330
| |
* If server requires no ticket, or user is "none", or a ticket
* is already cached, zero the request type
*/
tr.type = AuthTreq;
|
|
1993/0731
| |
if(strcmp(up->user, "none") == 0 || s->authid[0] == 0)
|
|
1993/0330
| |
tr.type = 0;
|
|
1993/0731
| |
else{
lock(s);
for(cp = s->cache; cp; cp = cp->next)
if(strcmp(cp->t.cuid, up->user) == 0){
tr.type = 0;
break;
}
unlock(s);
}
|
|
2001/0527
| |
/* message sent; receive and decode reply */
m = devtab[c->type]->read(c, msg, MAXMSG, c->offset);
if(m <= 0)
error("EOF receiving fversion reply");
|
|
1993/0330
| |
/* create ticket request */
|
|
1993/0731
| |
memmove(tr.chal, s->schal, CHALLEN);
memmove(tr.authid, s->authid, NAMELEN);
memmove(tr.authdom, s->authdom, DOMLEN);
|
|
1993/0501
| |
memmove(tr.uid, up->user, NAMELEN);
|
|
1993/0330
| |
memmove(tr.hostid, eve, NAMELEN);
convTR2M(&tr, (char*)arg[1]);
|
|
2001/0527
| |
lock(c);
c->offset += m;
unlock(c);
|
|
1993/0330
| |
|
|
2001/0527
| |
n = convM2S(msg, m, &f);
if(n != m)
error("bad fversion conversion on reply");
if(f.type != Rversion)
error("unexpected reply type in fversion");
if(f.msize > msize)
error("server tries to increase msize in fversion");
if(f.msize<256 || f.msize>1024*1024)
error("nonsense value of msize in fversion");
kstrdup(&c->version, f.version);
c->iounit = f.msize;
free(msg);
poperror();
Return:
m = strlen(c->version);
if(m > arglen)
m = arglen;
memmove((char*)arg[2], c->version, m);
|
|
1997/0327
| |
cclose(c);
|
|
1993/0407
| |
poperror();
|
|
1993/0330
| |
return 0;
|
|
2001/0527
| |
return m;
|
|
1993/0330
| |
}
/*
* attach tickets to a session
*/
long
sysfauth(ulong *arg)
|
|
2001/0527
| |
sysfsession(ulong *arg)
|
|
1993/0330
| |
{
|
|
2001/0527
| |
Fcall f;
uchar *msg;
uint authlen, n, m;
|
|
1993/0330
| |
Chan *c;
char *ta;
Session *s;
Crypt *cp, *ncp, **l;
char tbuf[2*TICKETLEN];
|
|
2001/0527
| |
uvlong oo;
|
|
1993/0330
| |
validaddr(arg[1], 2*TICKETLEN, 0);
c = fdtochan(arg[0], OWRITE, 0, 1);
s = c->session;
|
|
1999/0331
| |
if(s == 0){
cclose(c);
|
|
1993/0330
| |
error("fauth must follow fsession");
|
|
1999/0331
| |
}
|
|
1993/0330
| |
cp = newcrypt();
|
|
2001/0527
| |
//BUG print("warning: stub fsession being used\n");
authlen = arg[2];
validaddr(arg[1], authlen, 1);
c = fdtochan(arg[0], ORDWR, 0, 1);
|
|
1993/0330
| |
if(waserror()){
|
|
1999/0331
| |
cclose(c);
|
|
1993/0330
| |
freecrypt(cp);
nexterror();
}
/* ticket supplied, use it */
ta = (char*)arg[1];
memmove(tbuf, ta, 2*TICKETLEN);
convM2T(tbuf, &cp->t, evekey);
if(cp->t.num != AuthTc)
error("bad AuthTc in ticket");
|
|
1993/0501
| |
if(strncmp(up->user, cp->t.cuid, NAMELEN) != 0)
|
|
1993/0330
| |
error("bad uid in ticket");
if(memcmp(cp->t.chal, s->schal, CHALLEN) != 0)
error("bad chal in ticket");
memmove(cp->tbuf, tbuf+TICKETLEN, TICKETLEN);
/* string onto local list, replace old version */
lock(s);
l = &s->cache;
for(ncp = s->cache; ncp; ncp = *l){
|
|
1993/0501
| |
if(strcmp(ncp->t.cuid, up->user) == 0){
|
|
1993/0330
| |
*l = ncp->next;
freecrypt(ncp);
break;
}
l = &ncp->next;
}
cp->next = s->cache;
s->cache = cp;
unlock(s);
|
|
1999/0331
| |
cclose(c);
|
|
1993/0330
| |
poperror();
return 0;
}
/*
* free a session created by fsession
*/
void
freesession(Session *s)
{
|
|
1993/0403
| |
Crypt *cp, *next;
|
|
1993/0330
| |
|
|
1993/0403
| |
for(cp = s->cache; cp; cp = next) {
next = cp->next;
|
|
1993/0330
| |
freecrypt(cp);
|
|
1993/0403
| |
}
|
|
1993/0330
| |
free(s);
}
/*
* called by mattach() to fill in the Tattach message
*/
ulong
authrequest(Session *s, Fcall *f)
{
|
|
2001/0503
| |
Authenticator a;
|
|
1993/0330
| |
Crypt *cp;
ulong id, dofree;
/* no authentication if user is "none" or if no ticket required by remote */
|
|
1993/0501
| |
if(s == 0 || s->authid[0] == 0 || strcmp(up->user, "none") == 0){
|
|
1993/0330
| |
memset(f->ticket, 0, TICKETLEN);
memset(f->auth, 0, AUTHENTLEN);
|
|
2001/0527
| |
if(c->flag & CMSG){
//BUG what to do?
((uchar*)arg[1])[0] = 0;
poperror();
cclose(c);
|
|
1993/0330
| |
return 0;
}
/* look for ticket in cache */
dofree = 0;
|
|
1993/0403
| |
lock(s);
|
|
1993/0330
| |
for(cp = s->cache; cp; cp = cp->next)
|
|
1993/0501
| |
if(strcmp(cp->t.cuid, up->user) == 0)
|
|
1993/0330
| |
break;
|
|
1993/0403
| |
id = s->cid++;
unlock(s);
|
|
1993/0330
| |
if(cp == 0){
/*
* create a ticket using hostkey, this solves the
* chicken and egg problem
*/
cp = newcrypt();
cp->t.num = AuthTs;
memmove(cp->t.chal, s->schal, CHALLEN);
|
|
1993/0501
| |
memmove(cp->t.cuid, up->user, NAMELEN);
memmove(cp->t.suid, up->user, NAMELEN);
|
|
1993/0330
| |
memmove(cp->t.key, evekey, DESKEYLEN);
convT2M(&cp->t, f->ticket, evekey);
dofree = 1;
} else
memmove(f->ticket, cp->tbuf, TICKETLEN);
/* create an authenticator */
|
|
2001/0503
| |
memmove(a.chal, s->schal, CHALLEN);
a.num = AuthAc;
a.id = id;
convA2M(&a, f->auth, cp->t.key);
|
|
1993/0330
| |
if(dofree)
freecrypt(cp);
return id;
}
/*
* called by mattach() to check the Rattach message
*/
void
authreply(Session *s, ulong id, Fcall *f)
{
|
|
2001/0503
| |
Authenticator a;
|
|
1993/0330
| |
Crypt *cp;
if(s == 0)
return;
|
|
1993/0403
| |
lock(s);
|
|
1993/0330
| |
for(cp = s->cache; cp; cp = cp->next)
|
|
1993/0501
| |
if(strcmp(cp->t.cuid, up->user) == 0)
|
|
1993/0330
| |
break;
|
|
1993/0403
| |
unlock(s);
|
|
1993/0330
| |
/* we're getting around authentication */
|
|
1993/0501
| |
if(s == 0 || cp == 0 || s->authid[0] == 0 || strcmp(up->user, "none") == 0)
|
|
1993/0330
| |
return;
|
|
2001/0503
| |
convM2A(f->rauth, &a, cp->t.key);
if(a.num != AuthAs){
|
|
1993/0330
| |
print("bad encryption type\n");
error("server lies");
|
|
2001/0527
| |
f.type = Tsession;
f.tag = NOTAG;
f.nchal = 0;
f.chal = (uchar*)"";
msg = smalloc(MAXMSG);
if(waserror()){
free(msg);
nexterror();
|
|
1993/0330
| |
}
|
|
2001/0503
| |
if(memcmp(a.chal, s->cchal, sizeof(a.chal))){
|
|
1993/0330
| |
print("bad returned challenge\n");
error("server lies");
|
|
1998/0512
| |
}
|
|
2001/0503
| |
if(a.id != id){
|
|
1993/0330
| |
print("bad returned id\n");
error("server lies");
}
}
|
|
2001/0527
| |
n = convS2M(&f, msg, MAXMSG);
if(n == 0)
error("bad fsession conversion on send");
|
|
1993/0330
| |
/*
* called by devcons() for #c/authenticate
*
* The protocol is
* 1) read ticket request from #c/authenticate
|
|
1993/0731
| |
* 2) write ticket+authenticator to #c/authenticate. if it matches
* the challenge the user is changed to the suid field of the ticket
|
|
1993/0330
| |
* 3) read authenticator (to confirm this is the server advertised)
*/
long
authread(Chan *c, char *a, int n)
{
Crypt *cp;
int i;
Ticketreq tr;
|
|
2001/0527
| |
lock(c);
oo = c->offset;
c->offset += n;
unlock(c);
|
|
1993/0330
| |
if(c->aux == 0){
/*
* first read returns a ticket request
*/
if(n != TICKREQLEN)
error(Ebadarg);
c->aux = newcrypt();
cp = c->aux;
|
|
2001/0527
| |
m = devtab[c->type]->write(c, msg, n, oo);
|
|
1993/0731
| |
|
|
1993/0330
| |
memset(&tr, 0, sizeof(tr));
tr.type = AuthTreq;
strcpy(tr.hostid, eve);
strcpy(tr.authid, eve);
strcpy(tr.authdom, hostdomain);
|
|
1993/0501
| |
strcpy(tr.uid, up->user);
|
|
1993/0330
| |
for(i = 0; i < CHALLEN; i++)
tr.chal[i] = nrand(256);
memmove(cp->a.chal, tr.chal, CHALLEN);
convTR2M(&tr, a);
} else {
/*
* subsequent read returns an authenticator
*/
|
|
1998/0422
| |
if(n < AUTHENTLEN)
|
|
1993/0330
| |
error(Ebadarg);
cp = c->aux;
|
|
1993/0731
| |
|
|
1993/0330
| |
cp->a.num = AuthAs;
memmove(cp->a.chal, cp->t.chal, CHALLEN);
cp->a.id = 0;
|
|
1993/0731
| |
convA2M(&cp->a, cp->tbuf, cp->t.key);
memmove(a, cp->tbuf, AUTHENTLEN);
|
|
1998/0422
| |
if(n >= AUTHENTLEN + TICKETLEN)
convT2M(&cp->t, a+AUTHENTLEN, nil);
|
|
1993/0330
| |
freecrypt(cp);
c->aux = 0;
|
|
2001/0527
| |
if(m < n){
lock(c);
c->offset -= n - m;
unlock(c);
error("short write in fsession");
|
|
1993/0330
| |
}
return n;
}
long
authwrite(Chan *c, char *a, int n)
{
Crypt *cp;
|
|
2001/0527
| |
/* message sent; receive and decode reply */
m = devtab[c->type]->read(c, msg, MAXMSG, c->offset);
if(m <= 0)
error("EOF receiving fsession reply");
|
|
1993/0330
| |
|
|
1993/0731
| |
if(n != TICKETLEN+AUTHENTLEN)
|
|
1993/0330
| |
error(Ebadarg);
if(c->aux == 0)
error(Ebadarg);
cp = c->aux;
|
|
2001/0527
| |
lock(c);
c->offset += m;
unlock(c);
|
|
1993/0731
| |
memmove(cp->tbuf, a, TICKETLEN);
convM2T(cp->tbuf, &cp->t, evekey);
|
|
1993/0330
| |
if(cp->t.num != AuthTs || memcmp(cp->a.chal, cp->t.chal, CHALLEN))
error(Eperm);
|
|
2001/0527
| |
n = convM2S(msg, m, &f);
if(n != m)
error("bad fsession conversion on reply");
if(f.type != Rsession)
error("unexpected reply type in fsession");
m = f.nchal;
if(m > authlen)
error(Eshort);
//BUG print("auth stuff ignored; noauth by default\n");
((uchar*)arg[1])[0] = 0;
|
|
1993/0731
| |
memmove(cp->tbuf, a+TICKETLEN, AUTHENTLEN);
convM2A(cp->tbuf, &cp->a, cp->t.key);
if(cp->a.num != AuthAc || memcmp(cp->a.chal, cp->t.chal, CHALLEN))
error(Eperm);
|
|
1993/0501
| |
memmove(up->user, cp->t.suid, NAMELEN);
|
|
1993/0330
| |
return n;
|
|
2001/0527
| |
free(msg);
poperror();
poperror();
cclose(c);
return m;
|
|
1993/0330
| |
}
/*
* called by devcons() for #c/authcheck
*
|
|
1993/0731
| |
* a write of a ticket+authenticator [+challenge+id] succeeds if they match
|
|
1993/0330
| |
*/
long
authcheck(Chan *c, char *a, int n)
|
|
2001/0527
| |
sysfauth(ulong *)
|
|
1993/0330
| |
{
Crypt *cp;
|
|
1993/0731
| |
char *chal;
ulong id;
|
|
1993/0330
| |
|
|
1993/0731
| |
if(n != TICKETLEN+AUTHENTLEN && n != TICKETLEN+AUTHENTLEN+CHALLEN+4)
|
|
1993/0330
| |
error(Ebadarg);
if(c->aux == 0)
c->aux = newcrypt();
cp = c->aux;
|
|
1993/0731
| |
memmove(cp->tbuf, a, TICKETLEN);
convM2T(cp->tbuf, &cp->t, evekey);
|
|
1993/0402
| |
if(cp->t.num != AuthTc)
|
|
1993/0330
| |
error(Ebadarg);
|
|
1993/0501
| |
if(strcmp(up->user, cp->t.cuid))
|
|
1993/0402
| |
error(cp->t.cuid);
|
|
1993/0731
| |
memmove(cp->tbuf, a+TICKETLEN, AUTHENTLEN);
convM2A(cp->tbuf, &cp->a, cp->t.key);
if(n == TICKETLEN+AUTHENTLEN+CHALLEN+4){
uchar *p = (uchar *)&a[TICKETLEN+AUTHENTLEN+CHALLEN];
id = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
chal = &a[TICKETLEN+AUTHENTLEN];
}else{
id = 0;
chal = cp->t.chal;
}
if(cp->a.num != AuthAs || memcmp(chal, cp->a.chal, CHALLEN) || cp->a.id != id)
|
|
1993/0330
| |
error(Eperm);
|
|
1993/0731
| |
return n;
|
|
2001/0527
| |
error("sysfauth unimplemented");
return -1;
|
|
1993/0731
| |
}
/*
|
|
1998/0404
| |
* reading authcheck after writing into it yields the
|
|
1998/0407
| |
* unencrypted ticket
|
|
1998/0404
| |
*/
long
authcheckread(Chan *c, char *a, int n)
{
Crypt *cp;
cp = c->aux;
if(cp == nil)
error(Ebadarg);
|
|
1998/0406
| |
if(n < TICKETLEN)
|
|
1998/0404
| |
error(Ebadarg);
convT2M(&cp->t, a, nil);
return sizeof(cp->t);
}
/*
|
|
1993/0731
| |
* called by devcons() for #c/authenticator
*
* a read after a write of a ticket (or ticket+id) returns an authenticator
* for that ticket.
*/
long
authentwrite(Chan *c, char *a, int n)
{
Crypt *cp;
if(n != TICKETLEN && n != TICKETLEN+4)
error(Ebadarg);
if(c->aux == 0)
c->aux = newcrypt();
cp = c->aux;
memmove(cp->tbuf, a, TICKETLEN);
convM2T(cp->tbuf, &cp->t, evekey);
if(cp->t.num != AuthTc || strcmp(cp->t.cuid, up->user)){
freecrypt(cp);
c->aux = 0;
error(Ebadarg);
}
if(n == TICKETLEN+4){
uchar *p = (uchar *)&a[TICKETLEN];
cp->a.id = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
}else
cp->a.id = 0;
return n;
}
|
|
1998/0407
| |
/*
* create an authenticator and return it and optionally the
|
|
1999/1224
| |
* unencrypted ticket
|
|
1998/0407
| |
*/
|
|
1993/0731
| |
long
authentread(Chan *c, char *a, int n)
{
Crypt *cp;
cp = c->aux;
if(cp == 0)
error("authenticator read must follow a write");
cp->a.num = AuthAc;
memmove(cp->a.chal, cp->t.chal, CHALLEN);
convA2M(&cp->a, cp->tbuf, cp->t.key);
|
|
1998/0404
| |
if(n >= AUTHENTLEN)
memmove(a, cp->tbuf, AUTHENTLEN);
|
|
1993/0428
| |
return n;
}
|
|
1993/0330
| |
void
authclose(Chan *c)
{
if(c->aux)
freecrypt(c->aux);
c->aux = 0;
}
/*
* called by devcons() for key device
*/
long
|
|
2001/0503/sys/src/9/port/auth.c:600,611 –
2001/0527/sys/src/9/port/auth.c:231,239
|
|
1993/0330
| |
long
userwrite(char *a, int n)
{
if(n >= NAMELEN)
error(Ebadarg);
|
|
2000/0710
| |
if(!iseve() || strcmp(a, "none") != 0)
|
|
1993/0330
| |
error(Eperm);
|
|
1993/0501
| |
memset(up->user, 0, NAMELEN);
strcpy(up->user, "none");
|
|
2001/0527
| |
kstrdup(&up->user, "none");
|
|
1995/0110
| |
up->basepri = PriNormal;
|
|
1993/0330
| |
return n;
}
|
|
2001/0503/sys/src/9/port/auth.c:618,636 –
2001/0527/sys/src/9/port/auth.c:246,264
|
|
1993/0330
| |
long
hostownerwrite(char *a, int n)
{
char buf[NAMELEN];
|
|
2001/0527
| |
char buf[128];
|
|
1993/0330
| |
if(!iseve())
error(Eperm);
if(n >= NAMELEN)
|
|
2001/0527
| |
if(n >= sizeof buf)
|
|
1993/0330
| |
error(Ebadarg);
memset(buf, 0, NAMELEN);
strncpy(buf, a, n);
if(buf[0] == 0)
|
|
2001/0527
| |
strncpy(buf, a, n+1);
if(buf[0] == '\0')
|
|
1993/0330
| |
error(Ebadarg);
|
|
2001/0527
| |
|
|
1994/1027
| |
renameuser(eve, buf);
|
|
1993/0330
| |
memmove(eve, buf, NAMELEN);
|
|
1993/0501
| |
memmove(up->user, buf, NAMELEN);
|
|
2001/0527
| |
kstrdup(&eve, buf);
kstrdup(&up->user, buf);
|
|
1995/0110
| |
up->basepri = PriNormal;
|
|
1993/0330
| |
return n;
}
|