authenticate/authvlib.cc
changeset 0 6f7a81934006
child 2 b3afb9f1e801
equal deleted inserted replaced
-1:000000000000 0:6f7a81934006
       
     1 // Copyright (C) 1999,2000 Bruce Guenter <bruceg@em.ca>
       
     2 //
       
     3 // This program is free software; you can redistribute it and/or modify
       
     4 // it under the terms of the GNU General Public License as published by
       
     5 // the Free Software Foundation; either version 2 of the License, or
       
     6 // (at your option) any later version.
       
     7 //
       
     8 // This program is distributed in the hope that it will be useful,
       
     9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    11 // GNU General Public License for more details.
       
    12 //
       
    13 // You should have received a copy of the GNU General Public License
       
    14 // along with this program; if not, write to the Free Software
       
    15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    16 
       
    17 #include <config.h>
       
    18 #include <stdlib.h>
       
    19 #include "ac/time.h"
       
    20 #include <unistd.h>
       
    21 #include "authvlib.h"
       
    22 #include "misc/exec.h"
       
    23 #include "misc/lookup.h"
       
    24 #include "vdomain/vdomain.h"
       
    25 
       
    26 #ifndef HAVE_GETHOSTNAME
       
    27 int gethostname(char *name, size_t len);
       
    28 #endif
       
    29 
       
    30 void set_domain(mystring& name, mystring& domain)
       
    31 {
       
    32   int sep = name.find_first_of(config->separators());
       
    33   if(sep >= 0) {
       
    34     domain = name.right(sep+1);
       
    35     name = name.left(sep);
       
    36   }
       
    37   else {
       
    38     domain = getenv("TCPLOCALHOST");
       
    39     if(!domain) {
       
    40       char tmp[256];
       
    41       if(gethostname(tmp, 256))
       
    42 	fail_temporary("Error determining local host name");
       
    43       domain = tmp;
       
    44     }
       
    45   }
       
    46   if(!name)
       
    47     fail_login("Empty user name");
       
    48   if(!domain)
       
    49     fail_login("Empty domain name");
       
    50 }
       
    51 
       
    52 static vdomain* domain = 0;
       
    53 
       
    54 void set_user(const pwentry* pw)
       
    55 {
       
    56   pw->export_env();
       
    57   if(!!exec_presetuid && execute(exec_presetuid))
       
    58     fail_temporary("Execution of presetuid failed");
       
    59   if(setgid(pw->gid) == -1 ||
       
    60      setuid(pw->uid) == -1 ||
       
    61      chdir(pw->home.c_str()) == -1)
       
    62     fail_temporary("Bad user data in password file");
       
    63   domain = new vdomain(*pw);
       
    64   config = &domain->config;
       
    65 }
       
    66 
       
    67 static user_data* check(mystring fulluser, mystring password,
       
    68 			bool virtual_only)
       
    69 {
       
    70   mystring virtname;
       
    71   pwentry* basepw;
       
    72   if(!lookup_baseuser(fulluser, basepw, virtname))
       
    73     fail_login("Invalid or unknown base user or domain");
       
    74   presetenv("VUSER=", virtname);
       
    75   if(!virtname) {
       
    76     if(virtual_only)
       
    77       return 0;
       
    78     if(!basepw->authenticate(password))
       
    79       fail_login("Invalid or incorrect password");
       
    80     set_user(basepw);
       
    81     return new user_data(basepw, "", "");
       
    82   }
       
    83   else {
       
    84     set_user(basepw);
       
    85     vpwentry* vpw = domain->lookup(virtname, true);
       
    86     if(!vpw || !vpw->mailbox)
       
    87       fail_login("Invalid or unknown virtual user");
       
    88     if(!vpw->authenticate(password))
       
    89       fail_login("Invalid or incorrect password");
       
    90     if(vpw->expiry < (unsigned)time(0))
       
    91       fail_login("Account has expired");
       
    92     vpw->export_env();
       
    93     return new user_data(basepw, vpw->mailbox, vpw->name);
       
    94   }
       
    95 }
       
    96 
       
    97 user_data* authenticate(mystring name, mystring pass, mystring domain,
       
    98 			bool virtual_only)
       
    99 {
       
   100   mystring baseuser;
       
   101   if(!is_local(domain)) {
       
   102     mystring baseuser = find_virtual(domain);
       
   103     if(!!baseuser)
       
   104       name = baseuser + "-" + name;
       
   105   }
       
   106   user_data* result = check(name, pass, virtual_only);
       
   107   if(result && !!exec_postsetuid && execute(exec_postsetuid))
       
   108     fail_temporary("Execution of presetuid failed");
       
   109   return result;
       
   110 }