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

网络编程

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (c) 1989 Regents of the University of California.
  3.  * All rights reserved.  The Berkeley software License Agreement
  4.  * specifies the terms and conditions for redistribution.
  5.  */
  6. /*
  7.  * Copyright (c) 1997 by Qualcomm Incorporated.
  8.  */
  9. #include <config.h>
  10. #include <stdio.h>
  11. #include <sys/types.h>
  12. #include <pwd.h>
  13. #include<sys/stat.h>
  14. #include <string.h>
  15. # include <flock.h>
  16. #ifndef HAVE_INDEX
  17. # define index(s, c) strchr(s, c)
  18. #endif
  19. #if HAVE_STRINGS_H
  20. # include <strings.h>
  21. #endif
  22. #if HAVE_FCNTL_H
  23. # include <fcntl.h>
  24. #endif
  25. #if HAVE_SYS_FILE_H
  26. # include <sys/file.h>
  27. #endif
  28. #ifdef GDBM
  29. # include <gdbm.h>
  30. #else
  31. # if HAVE_NDBM_H
  32. #  include <ndbm.h>
  33. # endif
  34. #endif
  35. #include "popper.h"
  36. /* 
  37.  *  user:   Prompt for the user name at the start of a POP session
  38.  */
  39. int pop_user (p)
  40. POP     *   p;
  41. {
  42.     /* If there is an APOP database entry then don't allow a cleartext
  43.        password over the net */
  44. # ifdef APOP
  45. #ifdef GDBM
  46.     char apop_file[BUFSIZ];
  47. GDBM_FILE db;
  48. #else
  49.     char apop_dir[BUFSIZ];
  50.     DBM    *db;
  51. #endif
  52.     int    fid;
  53.     struct passwd *pw;
  54.     struct stat st;
  55.     datum key, value;
  56. # endif
  57. #ifdef KERBEROS
  58.     if (p->kerberos && strcmp(p->pop_parm[1], p->user)) {
  59. pop_log(p, LOG_WARNING, "%s: auth failed: %s.%s@@%s vs %s",
  60. p->client, kdata.pname, kdata.pinst, kdata.prealm, 
  61. p->pop_parm[1]);
  62.         return(pop_msg(p,POP_FAILURE,
  63.        "Wrong username supplied (%s vs. %.128s).", p->user,
  64.        p->pop_parm[1]));
  65.     }
  66. #endif
  67.     /*  Save the user name */
  68.     (void)strncpy(p->user, p->pop_parm[1], sizeof(p->user));
  69.     p->user[sizeof(p->user)-1] = 0;
  70. # ifdef APOP_ONLY
  71. return(pop_auth_fail(p, POP_FAILURE,
  72.     "You must use APOP authentication to connect to this server"));
  73. # endif
  74. # ifdef APOP
  75. /* If this call fails then the database is not accessable (doesn't
  76.    exist?) in which case we can ignore an APOP user trying to
  77.    access the popper with a cleartext password.
  78.          */
  79.     if (((pw = getpwnam(p->user)) != NULL) &&
  80. #ifdef GDBM
  81. ((db = gdbm_open(APOP, 512, GDBM_READER, 0, 0)) != NULL))
  82. #else
  83. ((db = dbm_open(APOP, O_RDONLY, 0)) != NULL)) 
  84. #endif
  85.     {
  86. #ifdef GDBM
  87.         (void) strncpy(apop_file, APOP, sizeof(apop_file) - 1);
  88. apop_file[sizeof(apop_file) - 1] = '';
  89. #else
  90. (void) strncpy(apop_dir, APOP, sizeof(apop_dir) - 5);
  91. # if defined(BSD44_DBM)
  92. (void) strcat(apop_dir, ".db");
  93. # else
  94. (void) strcat(apop_dir, ".dir");
  95. # endif
  96. #endif
  97. #ifdef GDBM
  98. if (stat (apop_file, &st) != -1 && (st.st_mode & 0777) != 0600) 
  99. #else
  100. if (stat (apop_dir, &st) != -1 && (st.st_mode & 0777) != 0600) 
  101. #endif
  102. {
  103. #ifdef GDBM
  104.     gdbm_close (db);
  105. #else
  106.     dbm_close (db);
  107. #endif
  108.     return(pop_auth_fail(p, POP_FAILURE,
  109. "POP authorization DB has wrong mode (0%o)",st.st_mode & 0777));
  110. }
  111. #ifdef GDBM
  112. fid = open(apop_file, O_RDONLY);
  113. #else
  114. fid = open(apop_dir, O_RDONLY);
  115. #endif
  116. if(fid == -1) {
  117.     int e = errno;
  118. #ifdef GDBM
  119.     gdbm_close (db);
  120. #else
  121.     dbm_close (db);
  122. #endif
  123.     return(pop_auth_fail(p, POP_FAILURE,
  124.     "unable to lock POP authorization DB (%s)", strerror(e)));
  125. }
  126. if (flock (fid, LOCK_SH) == -1) {
  127.     int e = errno;
  128.     (void) close(fid);
  129. #ifdef GDBM
  130.     gdbm_close (db);
  131. #else
  132.     dbm_close (db);
  133. #endif 
  134.     return(pop_auth_fail(p, POP_FAILURE,
  135.     "unable to lock POP authorization DB (%s)", strerror(e)));
  136. }
  137. key.dsize = strlen (key.dptr = p->user) + 1;
  138. #ifdef GDBM
  139. value = gdbm_fetch (db, key);
  140. gdbm_close(db);
  141. #else
  142. value = dbm_fetch (db, key);
  143. dbm_close (db);
  144. #endif
  145. (void) close(fid);
  146. if (value.dptr != NULL) {
  147.     return(pop_auth_fail(p, POP_FAILURE,
  148. "You must use APOP to connect to this server"));
  149. }
  150.     }
  151. #endif /* APOP */
  152.     /*  Tell the user that the password is required */
  153.     return (pop_msg(p,POP_SUCCESS,"Password required for %s.",p->user));
  154. }