commands/vadduser.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 <time.h>
       
    20 #include "fdbuf/fdbuf.h"
       
    21 #include "misc/passwdfn.h"
       
    22 #include "mystring/mystring.h"
       
    23 #include "config/configrc.h"
       
    24 #include "misc/pwcrypt.h"
       
    25 #include "vcommand.h"
       
    26 #include "cli/cli.h"
       
    27 
       
    28 const char* cli_program = "vadduser";
       
    29 const char* cli_help_prefix = "Add a user to a virtual domain\n";
       
    30 const char* cli_help_suffix = "";
       
    31 const char* cli_args_usage = "USERNAME [ALIAS1 ...]\n"
       
    32 "or vaddalias [-f ADDRESS] USERNAME [ALIAS1 ...]";
       
    33 const int cli_args_min = 1;
       
    34 const int cli_args_max = -1;
       
    35 
       
    36 static const char* o_userdir = 0;
       
    37 static cli_stringlist* o_forwards = 0;
       
    38 static const char* o_personal = 0;
       
    39 static int o_softquota = 0;
       
    40 static int o_hardquota = 0;
       
    41 static int o_msgsize = 0;
       
    42 static int o_msgcount = 0;
       
    43 static int o_expiry = 0;
       
    44 static int o_password = true;
       
    45 static int o_domailbox = true;
       
    46 static int o_quiet = false;
       
    47 
       
    48 // This program is used to set up a user within a virtual host.
       
    49 // If this program is reading from a tty,
       
    50 // it will then ask for a password (twice, to make sure you typed it in
       
    51 // correctly), otherwise it will read the password from the input with no
       
    52 // prompting.
       
    53 // It will then
       
    54 // add the user to the virtual password table in the current
       
    55 // directory and create a mail directory for the new user.
       
    56 // It will also add an entry for each of the named aliases.
       
    57 
       
    58 cli_option cli_options[] = {
       
    59   { 'c', "msgcount", cli_option::integer, 0, &o_msgcount,
       
    60     "Set the user's message count limit", 0 },
       
    61   { 'D', "no-mailbox", cli_option::flag, false, &o_domailbox,
       
    62     "Do not create a mailbox for this user", "true for vaddalias" },
       
    63   { 'd', "directory", cli_option::string, 0, &o_userdir,
       
    64     "Set the path to the user's mailbox", 0 },
       
    65   // Set the path to the user's mailbox.
       
    66   // Note that this directory is unconditionally prefixed with "./".
       
    67   { 'e', "expiry", cli_option::integer, 0, &o_expiry,
       
    68     "Set the account's expiry time (in seconds)", 0 },
       
    69   { 'f', "forward", cli_option::stringlist, 0, &o_forwards,
       
    70     "Add a forwarding address to this user", 0 },
       
    71   // Add a forwarding address to this user (this may be used multiple times).
       
    72   { 'P', "no-password", cli_option::flag, false, &o_password,
       
    73     "Do not ask for a password", 0 },
       
    74   // Do not ask for a password,
       
    75   // and instead set the pass phrase field to an unusable value.
       
    76   { 'p', "personal", cli_option::string, 0, &o_personal,
       
    77     "Set the user's personal information", 0 },
       
    78   { 'Q', "hardquota", cli_option::integer, 0, &o_hardquota,
       
    79     "Set the user's hard quota (in bytes)", 0 },
       
    80   { 'q', "softquota", cli_option::integer, 0, &o_softquota,
       
    81     "Set the user's soft quota (in bytes)", 0 },
       
    82   { 0, "quiet", cli_option::flag, true, &o_quiet,
       
    83     "Suppress all status messages", 0 },
       
    84   { 'z', "msgsize", cli_option::integer, 0, &o_msgsize,
       
    85     "Set the user's message size limit (in bytes)", 0 },
       
    86   {0}
       
    87 };
       
    88 
       
    89 // RETURN VALUE
       
    90 //
       
    91 // 0 if all steps were successful, non-zero otherwise.
       
    92 // If any of the steps fail, a diagnostic message is printed.
       
    93 
       
    94 // SEE ALSO
       
    95 //
       
    96 // vsetup(1)
       
    97 
       
    98 // NOTES
       
    99 // You must have either created the users subdirectory by hand or run the
       
   100 // F<vsetup> program before using this program.
       
   101 // 
       
   102 // This program expects the environment variable C<HOME> to be set, and
       
   103 // executes a change directory to the contents of it before starting.  It
       
   104 // is also required that you change user to the domain owner before using
       
   105 // these utilities.
       
   106 
       
   107 mystring list2str(cli_stringlist* list)
       
   108 {
       
   109   if(!list)
       
   110     return 0;
       
   111   mystring result = list->string;
       
   112   list = list->next;
       
   113   while(list) {
       
   114     result = result + mystring::NUL + list->string;
       
   115     list = list->next;
       
   116   }
       
   117   return result;
       
   118 }
       
   119 
       
   120 vpwentry* make_user(const mystring& name, const mystring& passcode)
       
   121 {
       
   122   mystring dir;
       
   123   if(o_domailbox) {
       
   124     if(o_userdir)
       
   125       dir = o_userdir;
       
   126     else
       
   127       dir = domain.userdir(name);
       
   128     dir = "./" + dir;
       
   129   }
       
   130 
       
   131   for(cli_stringlist* node = o_forwards; node; node = node->next) {
       
   132     response r = domain.validate_forward(node->string);
       
   133     if(!r) {
       
   134       if(!o_quiet)
       
   135 	ferr << argv0base << ": invalid forwarding address:\n  "
       
   136 	     << r.msg << endl;
       
   137       exit(1);
       
   138     }
       
   139   }
       
   140   
       
   141   vpwentry* vpw = new vpwentry(name.lower(), passcode, dir,
       
   142 			       list2str(o_forwards));
       
   143   vpw->set_defaults(true, true);
       
   144   
       
   145   vpw->personal = o_personal;
       
   146   vpw->hardquota = o_hardquota;
       
   147   vpw->softquota = o_softquota;
       
   148   vpw->msgcount = o_msgcount;
       
   149   vpw->msgsize = o_msgsize;
       
   150   vpw->expiry = o_expiry;
       
   151   //vpw->data = list2str(o_extra);
       
   152   
       
   153   return vpw;
       
   154 }
       
   155 
       
   156 void add_user(const mystring& user)
       
   157 {
       
   158   if(!domain.exists(user)) {
       
   159     mystring passcode = "*";
       
   160     if(o_password) {
       
   161       mystring passwd = getpasswd(argv0base);
       
   162       if(passwd.length() == 0)
       
   163 	exit(1);
       
   164       passcode = pwcrypt(passwd);
       
   165     }
       
   166     vpwentry* vpw = make_user(user, passcode);
       
   167     response resp = domain.set(vpw, true, vpw->mailbox);
       
   168     delete vpw;
       
   169     if(!resp) {
       
   170       if(!o_quiet)
       
   171 	ferr << argv0base << ": error adding the virtual user:\n  "
       
   172 	     << resp.msg << endl;
       
   173       exit(1);
       
   174     }
       
   175   }
       
   176   else {
       
   177     ferr << argv0base << ": error: user '" << user << "' already exists."
       
   178 	 << endl;
       
   179     exit(1);
       
   180   }
       
   181 }
       
   182 
       
   183 void add_alias(mystring user, mystring alias)
       
   184 {
       
   185   alias = alias.lower();
       
   186   user = user.lower();
       
   187   if(!domain.exists(alias)) {
       
   188     vpwentry vpw(alias, "*", 0, user);
       
   189     vpw.set_defaults(true, true);
       
   190     response resp = domain.set(&vpw, true);
       
   191     if(!resp)
       
   192       if(!o_quiet)
       
   193 	ferr << argv0base << ": warning: adding the alias '"
       
   194 	     << alias
       
   195 	     << "' failed:\n  "
       
   196 	     << resp.msg << endl;
       
   197     else
       
   198       if(!o_quiet)
       
   199 	fout << argv0base << ": alias '" << alias << "' successfully added"
       
   200 	     << endl;
       
   201   }
       
   202   else
       
   203     if(!o_quiet)
       
   204       ferr << argv0base << ": warning: alias '" << alias << "' already exists."
       
   205 	   << endl;
       
   206 }
       
   207 
       
   208 void set_defaults()
       
   209 {
       
   210   if(!strcmp(argv0base, "vaddalias"))
       
   211     o_domailbox = false;
       
   212   if(!o_hardquota)
       
   213     o_hardquota = config->default_hardquota();
       
   214   if(!o_softquota)
       
   215     o_softquota = config->default_softquota();
       
   216   if(!o_msgsize)
       
   217     o_msgsize = config->default_msgsize();
       
   218   if(!o_msgcount)
       
   219     o_msgcount = config->default_msgcount();
       
   220   if(!o_expiry)
       
   221     o_expiry = config->default_expiry();
       
   222   if(o_expiry != -1)
       
   223     o_expiry += time(0);
       
   224 }
       
   225 
       
   226 int cli_main(int argc, char* argv[])
       
   227 {
       
   228   if(!go_home())
       
   229     return 1;
       
   230 
       
   231   set_defaults();
       
   232   
       
   233   add_user(argv[0]);
       
   234   if(!o_quiet)
       
   235     fout << argv0base << ": user '" << argv[0] << "' successfully added"
       
   236 	 << endl;
       
   237   
       
   238   for(int i = 1; i < argc; i++)
       
   239     add_alias(argv[0], argv[i]);
       
   240   
       
   241   return 0;
       
   242 }