9auth.c 3.3 KB

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