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

WEB邮件程序

开发平台:

C/C++

  1. /*
  2. ** Copyright 1998 - 1999 Double Precision, Inc.  See COPYING for
  3. ** distribution information.
  4. */
  5. /*
  6. ** $Id: auth.c,v 1.24 2000/05/18 02:10:59 mrsam Exp $
  7. */
  8. #include "sqwebmail.h"
  9. #include "config.h"
  10. #if HAVE_SYSLOG_H
  11. #include <syslog.h>
  12. #endif
  13. #if HAVE_SYS_STAT_H
  14. #include <sys/stat.h>
  15. #endif
  16. #if HAVE_SYS_WAIT_H
  17. #include <sys/wait.h>
  18. #endif
  19. #if HAVE_UNISTD_H
  20. #include <unistd.h>
  21. #endif
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <ctype.h>
  25. #if HAVE_UNISTD_H
  26. #include <unistd.h>
  27. #endif
  28. #include <string.h>
  29. #include <errno.h>
  30. #include "authlib/auth.h"
  31. #include "authlib/authmod.h"
  32. #include "authlib/authstaticlist.h"
  33. #include "auth.h"
  34. #include "htmllibdir.h"
  35. extern int has_sqwebpass();
  36. extern int check_sqwebpass(const char *);
  37. static char *myhostname()
  38. {
  39. char    buf[512];
  40. static char *my_hostname=0;
  41. FILE *f;
  42. if (my_hostname == 0)
  43. {
  44. buf[0]=0;
  45. if ((f=fopen(HOSTNAMEFILE, "r")) != 0)
  46. {
  47. char *p;
  48. fgets(buf, sizeof(buf), f);
  49. fclose(f);
  50. if ((p=strchr(buf, 'n')) != 0)
  51. *p=0;
  52. }
  53. if (buf[0] == 0 && gethostname(buf, sizeof(buf)-1))
  54. strcpy(buf, "localhost");
  55. if ((my_hostname=malloc(strlen(buf)+1)) == 0)
  56. enomem();
  57. strcpy(my_hostname, buf);
  58. }
  59. return (my_hostname);
  60. }
  61. static int login_maildir(const char *maildir)
  62. {
  63. if (!maildir || !*maildir)
  64. maildir="Maildir";
  65. if (chdir(maildir)) return (-1);
  66. return (0);
  67. }
  68. struct preinfo {
  69. int i;
  70. int haswebpass;
  71. } ;
  72. static int pre_callback(struct authinfo *authinfo, void *vp)
  73. {
  74. const char *h=authinfo->homedir;
  75. struct preinfo *pi= (struct preinfo *)vp;
  76. if (!h) return (-1);
  77. pi->i=authinfo->staticindex;
  78. pi->haswebpass=0;
  79. #if ENABLE_WEBPASS
  80.    {
  81. const char *p=authinfo->maildir;
  82. char *buf;
  83. struct stat stat_buf;
  84. if (!p || !*p) p="Maildir";
  85. buf=malloc(strlen(h)+strlen(p)+sizeof(PASSFILE)+100);
  86. if (!buf)
  87. {
  88. perror("malloc");
  89. return (1);
  90. }
  91. if (*p == '/')
  92. strcpy(buf, p);
  93. else
  94. strcat(strcat(strcpy(buf, h), "/"), p);
  95. strcat(buf, "/" PASSFILE);
  96. if (stat(buf, &stat_buf) == 0) pi->haswebpass=1;
  97. free(buf);
  98.    }
  99. #endif
  100. return (0);
  101. }
  102. static int doauthlogin(struct authinfo *a, void *vp)
  103. {
  104.         authsuccess(a->homedir, a->sysuserid ? 0:a->sysusername,
  105. a->sysuserid, &a->sysgroupid,
  106. a->address, a->fullname);
  107. if (login_maildir(a->maildir))
  108. return (-1);
  109. return (0);
  110. }
  111. static const char *do_login(const char *u, const char *p, const char **driver)
  112. {
  113. char *buf;
  114. static char *uid=0;
  115. struct preinfo pi;
  116. int rc;
  117. /*
  118. ** We first need to check if sqwebmail saved its own password in sqwebmail-pass.
  119. ** To do that, we call the authlib preauthentication functions until we find
  120. ** one that accepts our userid.  However, if it succeeds, we will no longer
  121. ** as root.  Therefore, let's fork, and do our thing in the child proc.
  122. */
  123. pi.haswebpass=0;
  124. rc=authstaticlist_search(u, "webmail", MODULEFILE,
  125. &pre_callback, &pi);
  126. if (rc)
  127. return (0);
  128. #if ENABLE_WEBPASS
  129. if (pi.haswebpass)
  130. {
  131. if ((*authstaticlist[pi.i].auth_prefunc)(u, "webmail",
  132.                         &doauthlogin, 0))
  133. {
  134. return (0);
  135. }
  136. if (check_sqwebpass(p) == 0)
  137. {
  138. *driver=authstaticlist[pi.i].auth_name;
  139. return (u);
  140. }
  141. return (0);
  142. }
  143. #endif
  144. /* Let the authlib library check the password instead, then we'll
  145. ** adopt it as our own.
  146. */
  147. if ((buf=malloc(strlen(u)+strlen(p)+3)) == 0)
  148. enomem();
  149. strcat(strcat(strcat(strcpy(buf, u), "n"), p), "n");
  150. if (uid) free(uid);
  151. uid=(*authstaticlist[pi.i].auth_func)("webmail",
  152. AUTHTYPE_LOGIN, buf, 0, 0, 0);
  153. free(buf);
  154. if (uid != 0)
  155. {
  156. if (login_maildir(getenv("MAILDIR"))) enomem();
  157. *driver=authstaticlist[pi.i].auth_name;
  158. return (uid);
  159. }
  160. return (0);
  161. }
  162. /*
  163. ** The returned mailboxid is of the form user.authdriver
  164. **
  165. ** authdriver is included so that we can find the same authentication module
  166. ** quickly, for each request.  authdriver is appended, rather than prepended,
  167. ** because the logincache hashes on the first couple of characters of the id.
  168. */
  169. const char *login(const char *uid, const char *pass)
  170. {
  171. const char *driver;
  172. const char *p=do_login(uid, pass, &driver);
  173. static char *login_id_buf=0;
  174. if (p)
  175. {
  176. if (login_id_buf) free(login_id_buf);
  177. if ((login_id_buf=malloc(strlen(p)+strlen(driver)+2)) == 0)
  178. enomem();
  179. p=strcat(strcat(strcpy(login_id_buf, p), "."), driver);
  180. }
  181. return (p);
  182. }
  183. int prelogin(const char *u)
  184. {
  185. char *p=malloc(strlen(u)+1);
  186. char *driver;
  187. int i;
  188. if (!p) enomem();
  189. strcpy(p, u);
  190. if ((driver=strrchr(p, '.')) == 0)
  191. {
  192. free(p);
  193. enomem();
  194. }
  195. *driver++ = 0;
  196. for (i=0; authstaticlist[i].auth_name; i++)
  197. {
  198. if (strcmp(authstaticlist[i].auth_name, driver) == 0)
  199. {
  200. if ((*authstaticlist[i].auth_prefunc)(p, "webmail",
  201. &doauthlogin, 0) == 0)
  202. {
  203. free(p);
  204. return (0);
  205. }
  206. free(p);
  207. return (-1);
  208. }
  209. }
  210. free(p);
  211. return (-1);
  212. }
  213. const char *login_returnaddr()
  214. {
  215. const char *p=getenv("AUTHADDR");
  216. char *domain=myhostname();
  217. static char *addrbuf=0;
  218. if (!p) p="";
  219. if (addrbuf) free(addrbuf);
  220. addrbuf=malloc(strlen(domain)+strlen(p)+2);
  221. if (!addrbuf) enomem();
  222. strcpy(addrbuf, p);
  223. if (strchr(addrbuf, '@') == 0)
  224. strcat(strcat(addrbuf, "@"), domain);
  225. return (addrbuf);
  226. }
  227. const char *login_fromhdr()
  228. {
  229. const char *address=login_returnaddr();
  230. const char *fullname=getenv("AUTHFULLNAME");
  231. int l;
  232. const char *p;
  233. char *q;
  234. static char *hdrbuf=0;
  235. if (!fullname || !*fullname)
  236. return (address); /* That was easy */
  237. l=sizeof(""" <>")+strlen(address)+strlen(fullname);
  238. for (p=fullname; *p; p++)
  239. if (*p == '"' || *p == '\' || *p == '(' || *p == ')' ||
  240. *p == '<' || *p == '>') ++l;
  241. for (p=address; *p; p++)
  242. if (*p == '"' || *p == '\' || *p == '(' || *p == ')' ||
  243. *p == '<' || *p == '>') ++l;
  244. if (hdrbuf) free(hdrbuf);
  245. hdrbuf=malloc(l);
  246. if (!hdrbuf) enomem();
  247. q=hdrbuf;
  248. *q++='"';
  249. for (p=fullname; *p; p++)
  250. {
  251. if (*p == '"' || *p == '\' || *p == '(' || *p == ')' ||
  252. *p == '<' || *p == '>') *q++ = '\';
  253. *q++= *p;
  254. }
  255. *q++='"';
  256. *q++=' ';
  257. *q++='<';
  258. for (p=address; *p; p++)
  259. {
  260. if (*p == '"' || *p == '\' || *p == '(' || *p == ')' ||
  261. *p == '<' || *p == '>') *q++ = '\';
  262. *q++= *p;
  263. }
  264. *q++='>';
  265. *q=0;
  266. return (hdrbuf);
  267. }