1 #include "stdinc.h" 2 3 #include "9.h" 4 5 int 6 authRead(Fid* afid, void* data, int count) 7 { 8 AuthInfo *ai; 9 AuthRpc *rpc; 10 11 if((rpc = afid->rpc) == nil){ 12 vtSetError("not an auth fid"); 13 return -1; 14 } 15 16 switch(auth_rpc(rpc, "read", nil, 0)){ 17 default: 18 vtSetError("auth protocol not finished"); 19 return -1; 20 case ARdone: 21 if((ai = auth_getinfo(rpc)) == nil){ 22 vtSetError("%r"); 23 break; 24 } 25 if(ai->cuid == nil || *ai->cuid == '\0'){ 26 vtSetError("auth with no cuid"); 27 auth_freeAI(ai); 28 break; 29 } 30 assert(afid->cuname == nil); 31 afid->cuname = vtStrDup(ai->cuid); 32 auth_freeAI(ai); 33 if(Dflag) 34 fprint(2, "authRead cuname %s\n", afid->cuname); 35 assert(afid->uid == nil); 36 if((afid->uid = uidByUname(afid->cuname)) == nil){ 37 vtSetError("unknown user %#q", afid->cuname); 38 break; 39 } 40 return 0; 41 case ARok: 42 if(count < rpc->narg){ 43 vtSetError("not enough data in auth read"); 44 break; 45 } 46 memmove(data, rpc->arg, rpc->narg); 47 return rpc->narg; 48 case ARphase: 49 vtSetError("%r"); 50 break; 51 } 52 return -1; 53 } 54 55 int 56 authWrite(Fid* afid, void* data, int count) 57 { 58 assert(afid->rpc != nil); 59 if(auth_rpc(afid->rpc, "write", data, count) != ARok) 60 return -1; 61 return count; 62 } 63 64 int 65 authCheck(Fcall* t, Fid* fid, Fs* fsys) 66 { 67 Con *con; 68 Fid *afid; 69 uchar buf[1]; 70 71 /* 72 * Can't lookup with FidWlock here as there may be 73 * protocol to do. Use a separate lock to protect altering 74 * the auth information inside afid. 75 */ 76 con = fid->con; 77 if(t->afid == NOFID){ 78 /* 79 * If no authentication is asked for, allow 80 * "none" provided the connection has already 81 * been authenticatated. 82 * 83 * The console is allowed to attach without 84 * authentication. 85 */ 86 vtRLock(con->alock); 87 if(!con->isconsole && 88 (strcmp(fid->uname, unamenone) != 0 || !con->aok)){ 89 vtRUnlock(con->alock); 90 consPrint("attach %s as %s: connection not authenticated, not console\n", fsysGetName(fsys), fid->uname); 91 return 0; 92 } 93 vtRUnlock(con->alock); 94 95 if((fid->uid = uidByUname(fid->uname)) == nil){ 96 consPrint("attach %s as %s: unknown uname\n", fsysGetName(fsys), fid->uname); 97 return 0; 98 } 99 return 1; 100 } 101 102 if((afid = fidGet(con, t->afid, 0)) == nil){ 103 consPrint("attach %s as %s: bad afid\n", fsysGetName(fsys), fid->uname); 104 return 0; 105 } 106 107 /* 108 * Check valid afid; 109 * check uname and aname match. 110 */ 111 if(!(afid->qid.type & QTAUTH)){ 112 consPrint("attach %s as %s: afid not an auth file\n", fsysGetName(fsys), fid->uname); 113 fidPut(afid); 114 return 0; 115 } 116 if(strcmp(afid->uname, fid->uname) != 0 || afid->fsys != fsys){ 117 consPrint("attach %s as %s: afid is for %s as %s\n", fsysGetName(fsys), fid->uname, fsysGetName(afid->fsys), afid->uname); 118 fidPut(afid); 119 return 0; 120 } 121 122 vtLock(afid->alock); 123 if(afid->cuname == nil){ 124 if(authRead(afid, buf, 0) != 0 || afid->cuname == nil){ 125 vtUnlock(afid->alock); 126 consPrint("attach %s as %s: %R\n", fsysGetName(fsys), fid->uname); 127 fidPut(afid); 128 return 0; 129 } 130 } 131 vtUnlock(afid->alock); 132 133 assert(fid->uid == nil); 134 if((fid->uid = uidByUname(afid->cuname)) == nil){ 135 consPrint("attach %s as %s: unknown cuname %s\n", fsysGetName(fsys), fid->uname, afid->cuname); 136 fidPut(afid); 137 return 0; 138 } 139 140 vtMemFree(fid->uname); 141 fid->uname = vtStrDup(afid->cuname); 142 fidPut(afid); 143 144 /* 145 * Allow "none" once the connection has been authenticated. 146 */ 147 vtLock(con->alock); 148 con->aok = 1; 149 vtUnlock(con->alock); 150 151 return 1; 152 } 153