DMail comes with source and binary examples of NWAuth and wadduser, you should examine
the source and modify wadduser.htm so that it only allows the users to automatically
create their own accounts (it has extra functions which you would not want them to be able
to do)
How do I add extra fields to wadduser?
To add extra fields in wadduser.htm for storing more information about
the user, you will need to do the following:
- Add the input text boxes and their appropriate variables in HTML to
wadduser.htm (or the pages that you
want them on)
- Modify the source of the CGI wadduser (wadduser.c) so that it records
the information given
- Recompile wadduser.c (which requires linking
to nwauth.c)
- Replace wadduser.exe in your cgi or scripts directory with your new
version
The page that calls the wadduser CGI (wadduser.htm) has a form on it
that calls the CGI as its action to perform when it is submitted,
i.e when one of the buttons is pressed. E.g.
action="http://server.com/scripts/wadduser.exe" calls the
wadduser cgi from the scripts directory on the server.com web server.
The CGI works out which of the buttons on the page was pressed and
carries out the appropriate action.
The function below web_add (from wadduser.c) is called when you
click on
the "add" button on the example wadduser.htm page.
The form also has a number of variables that are passed to the CGI
as part of the action of submitting the form, e.g. name, username,
password. To add more fields, you will need to add more such input fields to
the web page, in this form,
<input type="text" name="username" size="20">
So to add a field to get the person's hobby, you could add to
wadduser.htm
<input type="text" name="hobby" size="20">
Then you need to decide what you want the CGI to do with the information
in the fields that you add.
The three lines in the function below,
fprintf(f,"%s|",form_find("phone"));
fprintf(f,"%s|",form_find("fax"));
fprintf(f,"%s|",form_find("comments"));
search the form that is submitted by the wadduser.htm page for the
fields, phone, fax and comments, and if it finds them then it prints them
into the log file, adduser.log. If it cannot find them, for example,
if there is no such input
field on the web page (this is the case with the example wadduser.htm -
there are no input boxes for phone, fax and comments) or the user has
not entered anything in the box, then
it will simply enter an empty string.
So to make wadduser log the person's hobby entry, you could add
this line below the three above,
fprintf(f,"%s|",form_find("hobby"));
The function below ONLY writes the username, password and name entries
to the nwauth.txt password file, but it writes to the log file, adduser.log, a whole bunch of
input fields that don't exist. Note that NWAuth only takes three fields,
'username', 'password' and 'other'. It is the 'other' field into
which you can add
your own fields. The function below adds the field 'name' into the
'other' field in the following format,
name="the person's full name"
The 'other' field can take as many fields as you want (until the information
reaches the BFSZ definition, when you will get buffer over flows!)
simply
make sure that each field has the correct format and that they are separated
by a space.
So, to make the CGI write the hobby field onto the end of the
'other' field
in nwauth.txt you should change the line in the function below from,
sprintf(bf,"name=\"%s\"",name);
to
sprintf(bf,"name=\"%s\" hobby=\"%s\"",name,form_find(hobby));
This will result in nwauth.txt lines like,
bob:a234h6:name="Bob Smith" hobby="ping pong"
for the username bob, which has a password of something we
cannot read as it is encrypted, and a full name of 'Bob Smith' and a
hobby of 'ping pong'.
int web_add(void)
{
FILE *f;
char username[BFSZ],password[BFSZ],name[BFSZ];
char bf[BFSZ];
/* Check the user has filled in the required fields */
if (!check_value("Name","name","")) return 0;
if (!check_value("Username","username","")) return 0;
if (!check_value("Password","password","")) return 0;
f = fopen("adduser.log","a");
if (f==NULL) { printf("Could not write file\n"); return 0;}
fprintf(f,"%s|Add|",get_date());
fprintf(f,"%s|",mygetenv("REMOTE_ADDR"));
fprintf(f,"%s|",form_find("username"));
fprintf(f,"%s|",form_find("name"));
/* These are optional form elements to record */
fprintf(f,"%s|",form_find("phone"));
fprintf(f,"%s|",form_find("fax"));
fprintf(f,"%s|",form_find("comments"));
fprintf(f,"\n");
fclose(f);
ncpy(username,form_find("username"),BFSZ-1);
ncpy(password,form_find("password"),BFSZ-1);
ncpy(name,form_find("name"),BFSZ-1);
strlwr(username); /* Only allow lower case usernames */
do_header("Adding user");
printf("<pre>");
if (auth_exists(username)) {
printf("Sorry, a user by that name already exists\n");
} else {
sprintf(bf,"name=\"%s\"",name);
auth_set(username,password,bf);
showfile("added.htm");
}
printf("</pre>");
do_footer();
return 0;
}
Q:I want to have two different types of users. I want one
group to have both pop and web access to their mail, and I want the
other group to have web access only. How would I set this up? Would
I need to run two seperate servers? I plan to authenticate using
an external authentication module (talking to a MS SQL 6.5 database).
A:Yes, you can run two separate servers, or you can make an external
authentication module flag some users as being only allowed web
access.
The trick is that DPOP only has the ip_address that the user
connected from to know whether the user has connected from CWMail or with
another email client direct to the POP server. DPOP passes this
ipaddress to the external authentication module.
So,
1. If you run two separate servers then you can use the
user_ip_address setting on one of the servers to only allow connections
to that server from
the ip address of the CWMail machine. Each server then either needs
its own authentication database or you need an external
authentication routine for each server which cannot 'see' the other server's
group of users in the database.
2. The nicer way is to make your user database have a flag for each
user to say whether they are allowed to connect directly to the POP
server or not, and then make your external authentication routine
check this flag, and reject the connection if they have not connected
from the appropriate IP address. The IP address that the user
connects from is given in the authentication request by DPOP, e.g.
check username password ipaddress
So your authentication routine needs to check the "direct dpop
connection allowed" flag and, if it is false, it should check the
ipaddress passed against your CWMail server(s)'s ip address and
only allow the connection if it does not match. This is an example -
you do not necessarily have to do it this way. The fact that the
connection from IP address is passed to the external authentication
module is the important point.
If I have not pointed it out before we also have the source code to
another customer's SQL authentication module which I can give to
you if it would help.
For more information contact
support-dmail@netwinsite.com