/[mailutils]/mailutils/pop3d/user.c
ViewVC logotype

Diff of /mailutils/pop3d/user.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.26 by gray, Fri Jul 26 11:23:04 2002 UTC revision 1.27 by gray, Tue Aug 13 13:24:57 2002 UTC
# Line 17  Line 17 
17    
18  #include "pop3d.h"  #include "pop3d.h"
19    
 #ifdef HAVE_MYSQL  
 # include "../MySql/MySql.h"  
 #endif  
   
 #ifdef USE_LIBPAM  
 #define COPY_STRING(s) (s) ? strdup(s) : NULL  
   
 static char *_pwd;  
 static char *_user;  
 static int _perr = 0;  
   
 #define PAM_ERROR if (_perr || (pamerror != PAM_SUCCESS)) \  
     goto pam_errlab;  
   
 static int  
 PAM_gnupop3d_conv (int num_msg, const struct pam_message **msg,  
                    struct pam_response **resp, void *appdata_ptr)  
 {  
   int replies = 0;  
   struct pam_response *reply = NULL;  
   (void)appdata_ptr;  
   
   reply = malloc (sizeof (*reply) * num_msg);  
   if (!reply)  
     return PAM_CONV_ERR;  
   
   for (replies = 0; replies < num_msg; replies++)  
     {  
       switch (msg[replies]->msg_style)  
         {  
         case PAM_PROMPT_ECHO_ON:  
           reply[replies].resp_retcode = PAM_SUCCESS;  
           reply[replies].resp = COPY_STRING (_user);  
           /* PAM frees resp */  
           break;  
   
         case PAM_PROMPT_ECHO_OFF:  
           reply[replies].resp_retcode = PAM_SUCCESS;  
           reply[replies].resp = COPY_STRING (_pwd);  
           /* PAM frees resp */  
           break;  
   
         case PAM_TEXT_INFO:  
         case PAM_ERROR_MSG:  
           reply[replies].resp_retcode = PAM_SUCCESS;  
           reply[replies].resp = NULL;  
           break;  
   
         default:  
           free (reply);  
           _perr = 1;  
           return PAM_CONV_ERR;  
         }  
     }  
   *resp = reply;  
   return PAM_SUCCESS;  
 }  
   
 static struct pam_conv PAM_conversation = { &PAM_gnupop3d_conv, NULL };  
 #endif /* USE_LIBPAM */  
   
 /* Basic user authentication. This also takes the PASS command and verifies  
    the user name and password. Calls setuid() upon successful verification,  
    otherwise it will (likely) return ERR_BAD_LOGIN */  
   
20  int  int
21  pop3d_user (const char *arg)  pop3d_user (const char *arg)
22  {  {
23    char *buf, pass[POP_MAXCMDLEN], *tmp, *cmd;    char *buf, pass[POP_MAXCMDLEN], *tmp, *cmd;
   struct passwd *pw;  
24    int status;    int status;
25    int lockit = 1;    int lockit = 1;
26    char *mailbox_name = NULL;    struct mu_auth_data *auth_data;
27      
28    if (state != AUTHORIZATION)    if (state != AUTHORIZATION)
29      return ERR_WRONG_STATE;      return ERR_WRONG_STATE;
30    
# Line 118  pop3d_user (const char *arg) Line 52  pop3d_user (const char *arg)
52        free (tmp);        free (tmp);
53      }      }
54    
55    if (strlen (cmd) > 4)    if (strcasecmp (cmd, "PASS") == 0)
56      {      {
57        free (cmd);        int rc;
       return ERR_BAD_CMD;  
     }  
58    
   if ((strcasecmp (cmd, "PASS") == 0))  
     {  
59        free (cmd);        free (cmd);
60    
61  #ifdef _USE_APOP  #ifdef _USE_APOP
# Line 139  pop3d_user (const char *arg) Line 69  pop3d_user (const char *arg)
69          }          }
70  #endif  #endif
71    
72        pw = mu_getpwnam (arg);        auth_data = mu_get_auth_by_name (arg);
73    
74        if (pw == NULL)        if (auth_data == NULL)
75          {          {
76            syslog (LOG_INFO, "User '%s': nonexistent", arg);            syslog (LOG_INFO, "User '%s': nonexistent", arg);
77            return ERR_BAD_LOGIN;            return ERR_BAD_LOGIN;
78          }          }
79    
80  #ifndef USE_LIBPAM        rc = mu_authenticate (auth_data, pass);
81        if (pw->pw_uid < 1)        openlog ("gnu-pop3d", LOG_PID, log_facility);
         return ERR_BAD_LOGIN;  
       if (strcmp (pw->pw_passwd, (char *) crypt (pass, pw->pw_passwd)))  
         {  
 #ifdef HAVE_SHADOW_H  
           struct spwd *spw;  
           spw = getspnam ((char *) arg);  
 #ifdef HAVE_MYSQL  
           if (spw == NULL)  
             spw = getMspnam (arg);  
 #endif /* HAVE_MYSQL */  
           if (spw == NULL || strcmp (spw->sp_pwdp,  
                                      (char *) crypt (pass, spw->sp_pwdp)))  
 #endif /* HAVE_SHADOW_H */  
             {  
               syslog (LOG_INFO, "User '%s': authentication failed", arg);  
               return ERR_BAD_LOGIN;  
             }  
         }  
 #else /* !USE_LIBPAM */  
       {  
         pam_handle_t *pamh;  
         int pamerror;  
         _user = (char *) arg;  
         _pwd = pass;  
         /* libpam doesn't log to LOG_MAIL */  
         closelog ();  
         pamerror = pam_start (pam_service, arg, &PAM_conversation, &pamh);  
         PAM_ERROR;  
         pamerror = pam_authenticate (pamh, 0);  
         PAM_ERROR;  
         pamerror = pam_acct_mgmt (pamh, 0);  
         PAM_ERROR;  
         pamerror = pam_setcred (pamh, PAM_ESTABLISH_CRED);  
       pam_errlab:  
         pam_end (pamh, PAM_SUCCESS);  
         openlog ("gnu-pop3d", LOG_PID, log_facility);  
         if (pamerror != PAM_SUCCESS)  
           {  
             syslog (LOG_INFO, "User '%s': authentication failed", _user);  
             return ERR_BAD_LOGIN;  
           }  
       }  
 #endif /* USE_LIBPAM */  
82    
83        if (pw->pw_uid > 0 && !mu_virtual_domain)        if (rc)
         {  
           setuid (pw->pw_uid);  
           mailbox_name = malloc (strlen (mu_path_maildir) +  
                                  strlen (pw->pw_name) + 1);  
           if (!mailbox_name)  
             {  
               syslog (LOG_ERR, "Not enough memory");  
               return ERR_UNKNOWN;  
             }  
           sprintf (mailbox_name, "%s%s", mu_path_maildir, pw->pw_name);  
         }  
       else if (mu_virtual_domain)  
84          {          {
85            mailbox_name = calloc (strlen (pw->pw_dir) + strlen ("/INBOX"), 1);            syslog (LOG_INFO, "User '%s': authentication failed", arg);
86            sprintf (mailbox_name, "%s/INBOX", pw->pw_dir);            mu_auth_data_free (auth_data);
87              return ERR_BAD_LOGIN;
88          }          }
89        }
90      else if (strcasecmp (cmd, "QUIT") == 0)
91        {
92          syslog (LOG_INFO, "Possible probe of account '%s'", arg);
93          free (cmd);
94          return pop3d_quit (pass);
95        }
96      else
97        {
98          free (cmd);
99          return ERR_BAD_CMD;
100        }
101    
102        if ((status = mailbox_create (&mbox, mailbox_name)) != 0    if (auth_data->change_uid)
103            || (status = mailbox_open (mbox, MU_STREAM_RDWR)) != 0)      setuid (auth_data->uid);
104      
105      if ((status = mailbox_create (&mbox, auth_data->mailbox)) != 0
106          || (status = mailbox_open (mbox, MU_STREAM_RDWR)) != 0)
107        {
108          mailbox_destroy (&mbox);
109          /* For non existent mailbox, we fake.  */
110          if (status == ENOENT)
111          {          {
112            mailbox_destroy (&mbox);            if (mailbox_create (&mbox, "/dev/null") != 0
113            /* For non existent mailbox, we fake.  */                || mailbox_open (mbox, MU_STREAM_READ) != 0)
           if (status == ENOENT)  
             {  
               if (mailbox_create (&mbox, "/dev/null") != 0  
                   || mailbox_open (mbox, MU_STREAM_READ) != 0)  
                 {  
                   state = AUTHORIZATION;  
                   free (mailbox_name);  
                   return ERR_UNKNOWN;  
                 }  
             }  
           else  
114              {              {
115                state = AUTHORIZATION;                state = AUTHORIZATION;
116                free (mailbox_name);                mu_auth_data_free (auth_data);
117                return ERR_MBOX_LOCK;                return ERR_UNKNOWN;
118              }              }
           lockit = 0;           /* Do not attempt to lock /dev/null ! */  
119          }          }
120        free (mailbox_name);        else
   
       if (lockit && pop3d_lock ())  
121          {          {
           mailbox_close (mbox);  
           mailbox_destroy (&mbox);  
122            state = AUTHORIZATION;            state = AUTHORIZATION;
123              mu_auth_data_free (auth_data);
124            return ERR_MBOX_LOCK;            return ERR_MBOX_LOCK;
125          }          }
126          lockit = 0;               /* Do not attempt to lock /dev/null ! */
       username = strdup (pw->pw_name);  
       if (username == NULL)  
         pop3d_abquit (ERR_NO_MEM);  
       state = TRANSACTION;  
   
       pop3d_outf ("+OK opened mailbox for %s\r\n", username);  
   
       /* mailbox name */  
       {  
         url_t url = NULL;  
         size_t total = 0;  
         mailbox_get_url (mbox, &url);  
         mailbox_messages_count (mbox, &total);  
         syslog (LOG_INFO, "User '%s' logged in with mailbox '%s' (%d msgs)",  
                 username, url_to_string (url), total);  
       }  
       return OK;  
127      }      }
128    else if (strcasecmp (cmd, "QUIT") == 0)    
129      if (lockit && pop3d_lock ())
130      {      {
131        syslog (LOG_INFO, "Possible probe of account '%s'", arg);        mailbox_close (mbox);
132        free (cmd);        mailbox_destroy (&mbox);
133        return pop3d_quit (pass);        mu_auth_data_free (auth_data);
134      }        state = AUTHORIZATION;
135          return ERR_MBOX_LOCK;
136        }
137      
138      username = strdup (auth_data->name);
139      if (username == NULL)
140        pop3d_abquit (ERR_NO_MEM);
141      state = TRANSACTION;
142    
143      mu_auth_data_free (auth_data);
144    
145      pop3d_outf ("+OK opened mailbox for %s\r\n", username);
146    
147      /* mailbox name */
148      {
149        url_t url = NULL;
150        size_t total = 0;
151        mailbox_get_url (mbox, &url);
152        mailbox_messages_count (mbox, &total);
153        syslog (LOG_INFO, "User '%s' logged in with mailbox '%s' (%d msgs)",
154                username, url_to_string (url), total);
155      }
156      return OK;
157    
   free (cmd);  
   return ERR_BAD_LOGIN;  
158  }  }
159    
160    
161    

Legend:
Removed from v.1.26  
changed lines
  Added in v.1.27

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26