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