authdaemonlib.c
上传用户:s81996212
上传日期:2007-01-04
资源大小:722k
文件大小:4k
源码类别:

WEB邮件程序

开发平台:

C/C++

  1. /*
  2. ** Copyright 2000 Double Precision, Inc.  See COPYING for
  3. ** distribution information.
  4. */
  5. #include "auth.h"
  6. #include "authmod.h"
  7. #include "authstaticlist.h"
  8. #include "authsasl.h"
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #if HAVE_UNISTD_H
  13. #include <unistd.h>
  14. #endif
  15. #include <fcntl.h>
  16. #include        <sys/types.h>
  17. #include        <sys/socket.h>
  18. #include        <sys/un.h>
  19. #include        <sys/time.h>
  20. #include        <unistd.h>
  21. #include        <stdlib.h>
  22. #include        <stdio.h>
  23. #include        <errno.h>
  24. #include <syslog.h>
  25. #include "authdaemonrc.h"
  26. #include "numlib/numlib.h"
  27. #define TIMEOUT 15
  28. static const char rcsid[]="$Id: authdaemonlib.c,v 1.1 2000/04/26 22:32:37 mrsam Exp $";
  29. static int opensock()
  30. {
  31. int s=socket(PF_UNIX, SOCK_STREAM, 0);
  32. struct  sockaddr_un skun;
  33. fd_set fdr;
  34. struct timeval tv;
  35. int rc;
  36. skun.sun_family=AF_UNIX;
  37. strcpy(skun.sun_path, AUTHDAEMONSOCK);
  38. if (s < 0)
  39. {
  40. syslog(LOG_CRIT, "authdaemon: socket() failed: %m");
  41. return (-1);
  42. }
  43.         if (fcntl(s, F_SETFL, O_NONBLOCK) < 0)
  44. {
  45. syslog(LOG_CRIT, "authdaemon: fcntl() failed: %m");
  46. close(s);
  47. return (-1);
  48. }
  49. if ( connect(s, &skun, sizeof(skun)) == 0)
  50. {
  51. /* That was easy, we're done. */
  52. if (fcntl(s, F_SETFL, 0) < 0)
  53. {
  54. close(s);
  55. return (-1);
  56. }
  57. return (s);
  58. }
  59. if ( errno != EINPROGRESS && errno != EWOULDBLOCK)
  60. {
  61. perror("authdaemon: connect");
  62. close(s);
  63. return (-1);
  64. }
  65.         /* Wait for the connection to go through, until the timeout expires */
  66. FD_ZERO(&fdr);
  67. FD_SET(s, &fdr);
  68. tv.tv_sec=TIMEOUT;
  69. tv.tv_usec=0;
  70. rc=select(s+1, 0, &fdr, 0, &tv);
  71.         if (rc <= 0 || !FD_ISSET(s, &fdr))
  72. {
  73. syslog(LOG_CRIT, "authdaemon: connect timed out");
  74. close(s);
  75. return (-1);
  76. }
  77. if ( connect(s, &skun, sizeof(skun)))
  78.         {
  79.                 if (errno != EISCONN)
  80. {
  81. syslog(LOG_CRIT, "authdaemon: connect failed: %m");
  82. close(s);
  83. return (-1);
  84. }
  85. }
  86.         if (fcntl(s, F_SETFL, 0) < 0)
  87. {
  88. syslog(LOG_CRIT, "authdaemon: fcntl() failed: %m");
  89. close(s);
  90. return (-1);
  91. }
  92. return (s);
  93. }
  94. static int writeauth(int fd, const char *p, unsigned pl)
  95. {
  96. fd_set  fds;
  97. struct  timeval tv;
  98. while (pl)
  99. {
  100. int     n;
  101. FD_ZERO(&fds);
  102. FD_SET(fd, &fds);
  103. tv.tv_sec=TIMEOUT;
  104. tv.tv_usec=0;
  105. if (select(fd+1, 0, &fds, 0, &tv) <= 0 || !FD_ISSET(fd, &fds))
  106. return (-1);
  107. n=write(fd, p, pl);
  108. if (n <= 0)     return (-1);
  109. p += n;
  110. pl -= n;
  111. }
  112. return (0);
  113. }
  114. static void readauth(int fd, char *p, unsigned pl)
  115. {
  116. time_t end_time, curtime;
  117. --pl;
  118. time(&end_time);
  119. end_time += TIMEOUT;
  120. while (pl)
  121. {
  122. int     n;
  123. fd_set  fds;
  124. struct  timeval tv;
  125. time(&curtime);
  126. if (curtime >= end_time)
  127. break;
  128. FD_ZERO(&fds);
  129. FD_SET(fd, &fds);
  130. tv.tv_sec=end_time - curtime;
  131. tv.tv_usec=0;
  132. if (select(fd+1, &fds, 0, 0, &tv) <= 0 || !FD_ISSET(fd, &fds))
  133. break;
  134. n=read(fd, p, pl);
  135. if (n <= 0)
  136. break;
  137. p += n;
  138. pl -= n;
  139. }
  140. *p=0;
  141. }
  142. int authdaemondo(const char *authreq,
  143. int (*func)(struct authinfo *, void *), void *arg)
  144. {
  145. int s=opensock();
  146. char buf[BUFSIZ];
  147. char *p, *q, *r;
  148. struct authinfo a;
  149. uid_t u;
  150. if (s < 0)
  151. {
  152. return (1);
  153. }
  154. if (writeauth(s, authreq, strlen(authreq)))
  155. {
  156. close(s);
  157. return (1);
  158. }
  159. readauth(s, buf, sizeof(buf));
  160. close(s);
  161. memset(&a, 0, sizeof(a));
  162. a.homedir="";
  163. p=buf;
  164. while (*p)
  165. {
  166. for (q=p; *q; q++)
  167. if (*q == 'n')
  168. {
  169. *q++=0;
  170. break;
  171. }
  172. if (strcmp(p, ".") == 0)
  173. {
  174. return ( (*func)(&a, arg));
  175. }
  176. if (strcmp(p, "FAIL") == 0)
  177. return (-1);
  178. r=strchr(p, '=');
  179. if (!r)
  180. {
  181. p=q;
  182. continue;
  183. }
  184. *r++=0;
  185. if (strcmp(p, "USERNAME") == 0)
  186. a.sysusername=r;
  187. else if (strcmp(p, "UID") == 0)
  188. {
  189. u=atol(r);
  190. a.sysuserid= &u;
  191. }
  192. else if (strcmp(p, "GID") == 0)
  193. {
  194. a.sysgroupid=atol(r);
  195. }
  196. else if (strcmp(p, "HOME") == 0)
  197. {
  198. a.homedir=r;
  199. }
  200. else if (strcmp(p, "ADDRESS") == 0)
  201. {
  202. a.address=r;
  203. }
  204. else if (strcmp(p, "NAME") == 0)
  205. {
  206. a.fullname=r;
  207. }
  208. else if (strcmp(p, "MAILDIR") == 0)
  209. {
  210. a.maildir=r;
  211. }
  212. else if (strcmp(p, "QUOTA") == 0)
  213. {
  214. a.quota=r;
  215. }
  216. else if (strcmp(p, "PASSWD") == 0)
  217. {
  218. a.passwd=r;
  219. }
  220. else if (strcmp(p, "PASSWD2") == 0)
  221. {
  222. a.clearpasswd=r;
  223. }
  224. p=q;
  225. }
  226. return (1);
  227. }
  228. void auth_daemon_cleanup()
  229. {
  230. }