unixnames.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. #include "all.h"
  2. static void uxfree(Unixid*);
  3. static Unixid * xfree;
  4. Unixidmap *idhead, *idtail;
  5. Unixscmap *scmap;
  6. #define UNUSED 0x7FFFFFFF
  7. /*
  8. * Sadly we have to use the IP address, since some systems (FreeBSD in particular)
  9. * do not believe it to be safe to depend on the hostname and so refuse to send it.
  10. * I dislike making this IP-centric, but so be it.
  11. * We keep a cache of host names in getdom.
  12. */
  13. Unixidmap *
  14. pair2idmap(char *server, ulong clientip)
  15. {
  16. Resub match;
  17. Unixscmap *m, *mp;
  18. Unixidmap *r;
  19. char dom[256];
  20. for(mp=0,m=scmap; m; mp=m,m=m->next){
  21. if(m->server[0] != server[0])
  22. continue;
  23. if(strcmp(m->server, server))
  24. continue;
  25. if(m->clientip != clientip)
  26. continue;
  27. if(mp){
  28. mp->next = m->next;
  29. m->next = scmap;
  30. scmap = m;
  31. }
  32. r = m->map;
  33. if(r->u.timestamp != 0 && r->g.timestamp != 0)
  34. return r;
  35. scmap = m->next;
  36. free(m);
  37. break;
  38. }
  39. if(rpcdebug)
  40. fprint(2, "looking for %lux\n", clientip);
  41. if(getdom(clientip, dom, sizeof dom)<0){
  42. clog("auth: unknown ip address");
  43. return nil;
  44. }
  45. if(rpcdebug)
  46. fprint(2, "dom is %s\n", dom);
  47. for(r=idhead; r; r=r->next){
  48. if(r->u.timestamp == 0 || r->g.timestamp == 0)
  49. continue;
  50. match.sp = match.ep = 0;
  51. if(regexec(r->sexp, server, &match, 1) == 0)
  52. continue;
  53. if(match.sp != server || match.ep <= match.sp || *match.ep)
  54. continue;
  55. match.sp = match.ep = 0;
  56. if(regexec(r->cexp, dom, &match, 1) == 0)
  57. continue;
  58. if(match.sp != dom || match.ep <= match.sp || *match.ep)
  59. continue;
  60. m = malloc(sizeof(Unixscmap));
  61. m->next = scmap;
  62. scmap = m;
  63. m->server = strstore(server);
  64. m->clientip = clientip;
  65. m->map = r;
  66. break;
  67. }
  68. return r;
  69. }
  70. int
  71. readunixidmaps(char *file)
  72. {
  73. Waitmsg *w;
  74. Biobuf *in;
  75. Unixidmap *m;
  76. int i, arc; char *arv[16], buf[256];
  77. char *l;
  78. // long savalarm;
  79. // savalarm = alarm(0);
  80. in = Bopen(file, OREAD);
  81. if(in == 0){
  82. clog("readunixidmaps can't open %s: %r\n", file);
  83. // alarm(savalarm);
  84. return -1;
  85. }
  86. for(m=idhead; m; m=m->next)
  87. m->flag = 0;
  88. while(l = Brdline(in, '\n')){ /* assign = */
  89. l[Blinelen(in)-1] = 0;
  90. arc = strparse(l, nelem(arv), arv);
  91. if(arc > 0 && arv[0][0] == '!'){
  92. ++arv[0];
  93. snprint(buf, sizeof buf, "/bin/%s", arv[0]);
  94. if(chatty){
  95. chat("!");
  96. for(i=0; i<arc; i++)
  97. chat(" %s", arv[i]);
  98. chat("...");
  99. }
  100. w = system(buf, arv);
  101. if(w == nil)
  102. chat("err: %r\n");
  103. else if(w->msg && w->msg[0])
  104. chat("status: %s\n", w->msg);
  105. else
  106. chat("OK\n");
  107. free(w);
  108. continue;
  109. }
  110. if(arc != 4)
  111. continue;
  112. for(m=idhead; m; m=m->next)
  113. if(strcmp(arv[0], m->server) == 0 &&
  114. strcmp(arv[1], m->client) == 0)
  115. break;
  116. if(m == 0){
  117. m = malloc(sizeof(Unixidmap));
  118. if(idtail)
  119. idtail->next = m;
  120. else
  121. idhead = m;
  122. idtail = m;
  123. m->next = 0;
  124. m->server = strstore(arv[0]);
  125. m->client = strstore(arv[1]);
  126. m->sexp = regcomp(m->server);
  127. m->cexp = regcomp(m->client);
  128. m->u.file = strstore(arv[2]);
  129. m->u.style = 'u';
  130. m->u.timestamp = 0;
  131. m->u.ids = 0;
  132. m->g.file = strstore(arv[3]);
  133. m->g.style = 'u';
  134. m->g.timestamp = 0;
  135. m->g.ids = 0;
  136. }else{
  137. if(!m->u.file || strcmp(m->u.file, arv[2]) != 0){
  138. m->u.file = strstore(arv[2]);
  139. m->u.timestamp = 0;
  140. }
  141. if(!m->g.file || strcmp(m->g.file, arv[3]) != 0){
  142. m->g.file = strstore(arv[3]);
  143. m->g.timestamp = 0;
  144. }
  145. }
  146. m->flag = 1;
  147. checkunixmap(&m->u);
  148. checkunixmap(&m->g);
  149. }
  150. Bterm(in);
  151. for(m=idhead; m; m=m->next)
  152. if(m->flag == 0){
  153. m->u.file = 0;
  154. m->u.timestamp = 0;
  155. uxfree(m->u.ids);
  156. m->u.ids = 0;
  157. m->g.file = 0;
  158. m->g.timestamp = 0;
  159. uxfree(m->g.ids);
  160. m->g.ids = 0;
  161. }
  162. // alarm(savalarm);
  163. return 0;
  164. }
  165. static void
  166. uxfree(Unixid *x)
  167. {
  168. Unixid *tail;
  169. int count=0;
  170. if(x){
  171. tail = x;
  172. if(tail->id < 0)
  173. abort();
  174. tail->id = UNUSED;
  175. while(tail->next){
  176. tail = tail->next;
  177. ++count;
  178. if(tail->id == UNUSED)
  179. abort();
  180. tail->id = UNUSED;
  181. }
  182. tail->next = xfree;
  183. xfree = x;
  184. }
  185. }
  186. int
  187. checkunixmap(Unixmap *u)
  188. {
  189. Dir *dir;
  190. dir = dirstat(u->file);
  191. if(dir == nil){
  192. clog("checkunixmap can't stat %s: %r\n", u->file);
  193. return -1;
  194. }
  195. if(u->timestamp > dir->mtime){
  196. free(dir);
  197. return 0;
  198. }
  199. uxfree(u->ids);
  200. u->ids = readunixids(u->file, u->style);
  201. u->timestamp = time(0);
  202. free(dir);
  203. return 1;
  204. }
  205. int
  206. name2id(Unixid **list, char *name)
  207. {
  208. Unixid *x, *xp;
  209. for(xp=0,x=*list; x; xp=x,x=x->next){
  210. if(x->name[0] == name[0] && strcmp(x->name, name) == 0){
  211. if(xp){
  212. xp->next = x->next;
  213. x->next = *list;
  214. *list = x;
  215. }
  216. return x->id;
  217. }
  218. }
  219. return -1;
  220. }
  221. char *
  222. id2name(Unixid **list, int id)
  223. {
  224. Unixid *x, *xp;
  225. for(xp=0,x=*list; x; xp=x,x=x->next){
  226. if(x->id == id){
  227. if(xp){
  228. xp->next = x->next;
  229. x->next = *list;
  230. *list = x;
  231. }
  232. return x->name;
  233. }
  234. }
  235. return "none";
  236. }
  237. void
  238. idprint(int fd, Unixid *xp)
  239. {
  240. while(xp){
  241. fprint(fd, "%d\t%s\n", xp->id, xp->name);
  242. xp = xp->next;
  243. }
  244. }
  245. /*
  246. * style '9': 3:tom:tom:
  247. * style 'u': sysadm:*:0:0:System-Administrator:/usr/admin:/bin/sh
  248. */
  249. Unixid *
  250. readunixids(char *file, int style)
  251. {
  252. Biobuf *in;
  253. char *l, *name = 0;
  254. Unixid *x, *xp = 0;
  255. int id = 0;
  256. in = Bopen(file, OREAD);
  257. if(in == 0){
  258. clog("readunixids can't open %s: %r\n", file);
  259. return 0;
  260. }
  261. while(l = Brdline(in, '\n')){ /* assign = */
  262. l[Blinelen(in)-1] = 0;
  263. switch(style){
  264. case '9':
  265. id = strtol(l, &l, 10);
  266. if(*l != ':')
  267. continue;
  268. name = ++l;
  269. l = strchr(l, ':');
  270. if(l == 0)
  271. continue;
  272. *l = 0;
  273. break;
  274. case 'u':
  275. name = l;
  276. l = strchr(l, ':');
  277. if(l == 0)
  278. continue;
  279. *l++ = 0;
  280. /* skip password */
  281. l = strchr(l, ':');
  282. if(l == 0)
  283. continue;
  284. id = strtol(l+1, 0, 10);
  285. break;
  286. default:
  287. panic("unknown unixid style %d\n", style);
  288. }
  289. if(id == UNUSED)
  290. id = -1; /* any value will do */
  291. if(!(x = xfree)) /* assign = */
  292. x = listalloc(1024/sizeof(Unixid), sizeof(Unixid));
  293. xfree = x->next;
  294. x->id = id;
  295. x->name = strstore(name);
  296. x->next = xp;
  297. xp = x;
  298. }
  299. Bterm(in);
  300. return xp;
  301. }