| Previous | Contents | Index |
Sites can override five aspects of the popstore and MessageStore by providing callable subroutines:
The last subroutine is of interest to sites who want to increase the security of popstore/msgstore passwords for example by comparing the proposed password to a dictionary or to a site-maintained history of previous passwords. See Section 14.3.
1 Note that on UNIX systems, this can be done using symbolic links; the popstore/msgstore will correctly follow hard and symbolic links. |
By default, the popstore/msgstore uses straightforward algorithms to compute elapsed connect times and disk storage over time:
elapsed_time := end_time - start_time
storage := (end_time - start_time) / (86400 seconds/hour) *
size / (1024 bytes/block)
|
elapsed_time
Elapsed time measured in units of seconds.end_time
Ending time measured in units of seconds elapsed since 1 January 1970 at 0:00:00.0.start_time
Starting time measured in units of seconds elapsed since 1 January 1970 at 0:00:00.0.storage
Amount of storage as measured in units of block days with 1 block equal to 1024 bytes.size
Size of the stored object as measured in units of bytes.
Sites wanting to use different algorithms can do so by supplying
executable subroutines via shared images. The subroutine to compute the
elapsed time must have the name compute_connect and be of
the form
#include <time.h> #ifdef __VMS # include "pmdf_com:popstore.h" #else # include "/pmdf/include/popstore.h" #endif uint32 compute_connect (start_time, end_time) time_t start_time; time_t end_time; |
compute_connect are as described
below and the subroutine must return the elapsed time, as measured in
seconds, between the starting and ending times: start_time
Starting time measured in units of seconds elapsed since 1 January 1970 at 0:00:00.0. Used for input only.end_time
Ending time measured in units of seconds elapsed since 1 January 1970 at 0:00:00.0. Used for input only.
A C code realization of the default algorithm used by the popstore/msgstore to compute connect time is given in Example 14-1.
Example 14-1 Default
compute_connect Subroutine |
|---|
#include <time.h>
#ifdef __VMS
# include "pmdf_com:popstore.h"
#else
# include "/pmdf/include/popstore.h"
#endif
uint32 compute_connect (start_time, end_time)
time_t start_time;
time_t end_time;
{
return ((uint32)difftime (end_time, start_time));
}
|
The subroutine to compute storage must have the name
compute_block_days and be of the form
#include <time.h>
#ifdef __VMS
# include "pmdf_com:popstore.h"
#else
# include "/pmdf/include/popstore.h"
#endif
void compute_block_days (start_time, end_time, size, result,
remainder)
time_t start_time;
time_t end_time;
uint32 size;
uint32 *result;
uint32 *remainder;
|
*result the storage as
measured in units of block days. In addition, the subroutine must
return in *remainder any roundoff, as measured in byte
seconds. start_time
Starting time measured in units of seconds elapsed since 1 January 1970 at 0:00:00.0. Used for input only.end_time
Ending time measured in units of seconds elapsed since 1 January 1970 at 0:00:00.0. Used for input only.result
Amount of storage as measured in units of block days with 1 block equal to 1024 bytes. Used for output only.remainder
Roundoff in storage as measured in units of byte seconds. Used for input and output. On input, this will be the roundoff left over from a previous computation and which should be incorporated into this new computation. On output, this should be set to the roundoff resulting from computing the result.
The default subroutine used by the popstore/msgstore is shown in Example 14-2.
Example 14-2 Default
compute_block_days Subroutine |
|---|
#include <time.h>
#ifdef __VMS
# include "pmdf_com:popstore.h"
#else
# include "/pmdf/include/popstore.h"
#endif
void compute_block_days (start_time, end_time, size, result,
remainder)
time_t start_time;
time_t end_time;
uint32 size;
uint32 *result;
uint32 *remainder;
{
double blocks, days, value;
days = difftime (end_time, start_time) / 86400.0;
blocks = size / 1024.0;
value = (days * blocks) + (*remainder / (86400.0 * 1024.0));
*result = (uint32)value;
*remainder = (uint32)((value - (uint32)value) * 86400.0 * 1024.0);
}
|
The COMPUTE_CONNECT and COMPUTE_BLOCK_DAYS
options must be used to point the popstore/msgstore at the shared image
or images containing the compute_connect and
compute_block_days subroutines. See Section 3.4 for
details. When linking the subroutines into shared images, use link
commands of the forms shown in Section 13.2.1. The subroutines can be
tested with the TEST command of the command line
management utility.
14.2 File Locations
By default, the popstore/msgstore stores all message files on the same
disk as described in Section 1.4. Likewise for account profile files
as described in Section 1.3.9. On UNIX systems, links --- symbolic or
hard --- can be used to relocate subdirectories in these trees thereby
allowing files to be spread across any number of disks. The
popstore/msgstore will automatically handle such links; no special
configuration of the popstore/msgstore is required to accomodate links.
Sites wanting to relocate the entire message or profile directory tree
to another disk should do so using either the UNIX PMDF tailor file,
the NT registry, or the OpenVMS popstore/msgstore logicals. On UNIX and
NT systems, manually move the tree in question and change the
corresponding PMDF_POPSTORE_MESSAGES or
PMDF_POPSTORE_PROFILES entry in the
/etc/pmdf_tailor file (UNIX) or registry (NT). On OpenVMS
systems, manually move the directory tree in question and then change
the corresponding definition of the PMDF_POPSTORE_MESSAGES
or PMDF_POPSTORE_PROFILES logical. Changing the values of
those logicals is best done by first seeing how they are defined in the
pmdf_startup.com procedure in the
SYS$STARTUP: directory. Then, create a
pmdf_site_startup.com command procedure which redefines
the logicals, pointing to the correct disk and directory. Place that
command procedure in the PMDF_COM: directory. It will then
be seen and executed by PMDF each time you boot your system.
Now, some sites can want to actually spread message or profile files across more than one disk. Again, UNIX systems can use symbolic links to accomplish this. However, OpenVMS systems lack such a mechanism. Consequently, an alternate mechanism for relocating files is provided for all platforms. This mechanism involves the use of site-supplied subroutines made available to the popstore/msgstore via shared images. When the popstore/msgstore needs to access a message or a profile file, it first generates a default path to the file and then checks for a site-supplied subroutine. If the subroutine does not exist, the default path is used. If the subroutine does exist, it is called with the file path and filename in question. The subroutine can then change the path to the file; the popstore/msgstore will use the changed path to access the file. In addition to supplying subroutines, text files listing the path to each directory tree must also be supplied. These text files are used when the popstore/msgstore must search for a message or profile file.
Only use this mechanism when actually spreading a profile or message file directory tree across more than one disk. Using this mechanism when merely moving an entire profile or message file directory tree to another disk is not worth the effort required and can be accomplished more easily using previously described mechanisms. |
The name of the subroutine to map message file filenames is
map_message_filename; the name of the subroutine to map
account profile filenames is map_profile_filename. Their
existence and location are made known to the popstore/msgstore using
the MAP_MESSAGE_FILENAME and MAP_PROFILE_FILENAME options documented in
Sections 3.4 and 3.3, respectively. Sites can
supply one or both of these subroutines. When linking the subroutines
into shared images, use link commands of the forms given in
Section 13.2.1.
The subroutines take the form
#ifdef __VMS
# include "pmdf_com:popstore.h"
#else
# include "/pmdf/include/popstore.h"
#endif
void map_message_filename (version, def_name, def_len, def_path_len,
new_name, new_len, max_new_len, new_path_len)
uint32 version
char *def_name;
int def_len;
int def_path_len;
char *new_name;
int *new_len;
int max_new_len;
int *new_path_len;
void map_profile_filename (version, def_name, def_len, def_path_len,
new_name, new_len, max_new_len, new_path_len)
uint32 version
char *def_name;
int def_len;
int def_path_len;
char *new_name;
int *new_len;
int max_new_len;
int *new_path_len;
|
version
Formap_message_filename, this argument is the current value of theMESSAGE_FILENAME_VERSIONoption. Formap_profile_filename, this argument is the current value of thePROFILE_FILENAME_VERSIONoption. Used for input only.def_name
The default file specification including the full path and filename. This string isNULLterminated. Used for input only.def_len
The length in bytes of the default file specification. The length does not include anyNULLterminator. Used for input only.def_path_len
The length in bytes of the path specification in the default file specification. That is, the firstdef_path_lenbytes ofdef_nameis the path specification for the file. Used for input only.new_name
The new file specification which should be used. This must include both the full path and filename for the file and must beNULLterminated. Note that the filename portion of the file specification must not be altered; only the path specification portion of the file specification can be changed. Thedefaultdirectory name in the path should not be removed---it is part of the popstore's user domain naming system.defaultis the default user domain. Used for output only.new_len
The length in bytes, not including theNULLterminator, of the new file specification. Used for output only.max_new_len
Maximum length in bytes ofnew_name, not including a trailingNULLterminator. The name passed back innew_namecan not exceed this length. Used for input only. Note that the following relationship will always hold:
def_path_len<= 252 bytes <=max_new_lennew_path_len
The length in bytes of the path specification portion of the new file specification. Used for output only.
The site-supplied subroutine is passed the default file specification
and must return on output a new file specification. If no change is to
be made to the file specification, then the input arguments should
simply be copied to the output arguments. If a change is made, the
resulting file specification must have the same filename. The
subroutine can only change the path portion of the file specification.
(On OpenVMS systems, this is the device and directory portion of the
specification.) Moreover, for profile file names, the
default directory name should be left untouched. That name
is part of the popstore's user domain naming system.
Note that for message filenames, the last character in the filename
portion of the specification indicates the value of the
MESSAGE_FILENAME_VERSION option which was in force when
the message file in question was initially created. The default value
for that option is 0. When implementing a
map_message_filename subroutine, it is a good idea to
increment that value to 1. Then your subroutine can
distinguish between files generated when no algorithm was in place and
files generated when an algorithm was first used. Yes, there's no
immediate value in doing this. However, should you then change your
algorithm, you will then want to distinguish between your new algorithm
and your old algorithm. When you change your algorithm, then again
increment the version number. You can then distinguish between the no
algorithm case, version 0, the original algorithm case,
version 1, and the revised algorithm case, version
2.
The command line management utility includes a
TEST command which should be used to test
map_message_filename and map_profile_filename
subroutines. Use that utility to test your subroutines before
integrating them into the popstore with the
MAP_MESSAGE_FILENAME and MAP_PROFILE_FILENAME
options. Moreover, when you use that TEST command, the
utility will tell you how each message or profile filename would be
mapped by your subroutine. That information is provided for each
message or user account currently used by the popstore. You can use
that information to help relocate each popstore file to the correct new
location required by your subroutine.
When a map_message_filename subroutine is provided, you
must also supply a corresponding
popstore_message_paths file. That file is a world readable
text file which should be placed in the PMDF table directory. For each
top-level directory tree used to store message files, a path to that
tree must be given in the text file. One path per line in the file.
Similarly, when a map_profile_filename subroutine is
provided, a corresponding
popstore_profile_paths file must be provided in the PMDF
table directory. These files are then used by the popstore when it must
conduct scans for message or profile files. Scans for profile files are
only done to rebuild the user database or to test a
map_profile_filename subroutine. However, scans for
message files happen regularly when the popstore's message bouncer
runs. An example file is given in Example 14-4.
A sample map_profile_filename is shown in Example 14-3.
That sample subroutine implements, for UNIX systems, a directory tree
split as depicted below:
| Default filename | New filename |
|---|---|
/pmdf/user/default/a/*
|
/disk0/profiles/default/a/*
|
| ... | ... |
/pmdf/user/default/m/*
|
/disk0/profiles/default/m/*
|
/pmdf/user/default/n/*
|
/disk1/profiles/default/n/*
|
| ... | ... |
/pmdf/user/default/z/*
|
/disk1/profiles/default/z/*
|
/pmdf/user/default/0/*
|
/disk2/profiles/default/0/*
|
| ... | ... |
/pmdf/user/default/9/*
|
/disk2/profiles/default/9/*
|
/pmdf/user/default/r/o/b/rob is relocated to
/disk1/profiles/default/r/o/b/rob. The
popstore_profile_paths file corresponding to this mapping
is shown in Example 14-4.
Example 14-3 UNIX
map_profile_filename Sample Subroutine |
|---|
#include <string.h>
#include "/pmdf/include/popstore.h"
void map_profile_filename (uint32 version, char *def_name,
int def_len, int def_path_len,
char *new_name, int *new_len,
int max_new_len, int *new_path_len)
{
char c;
/*
* We assume that def_name will be of the form
* /pmdf/user/domain/x/y/z/filename. This assumption is
* governed by the value of the option PMDF_POPSTORE_PROFILES
* in the /etc/pmdf_tailor file.
*/
strcpy (new_name, "/disk#/profiles/");
c = def_name[def_path_len-6];
if ('a' <= c && c <= 'm') new_name[5] = '0';
else if ('n' <= c && c <= 'z') new_name[5] = '1';
else new_name[5] = '2';
strcat (&new_name[16], &def_name[11]);
*new_path_len = def_path_len + 5;
*new_len = strlen (new_name);
}
|
Example 14-4 UNIX
/pmdf/table/popstore_profile_paths Sample File |
|---|
/disk0/profiles/ /disk1/profiles/ /disk2/profiles/ |
A similar example for OpenVMS systems is shown in Examples 14-5 and 14-6. That sample subroutine implements, the directory tree split as depicted below:
| Default filename | New filename |
|---|---|
PMDF_POPSTORE_PROFILES:[DEFAULT.A...]*.;
|
DISK0:[PROFILES.DEFAULT.A...]*.;
|
| ... | ... |
PMDF_POPSTORE_PROFILES:[DEFAULT.M...]*.;
|
DISK0:[PROFILES.DEFAULT.M...]*.;
|
PMDF_POPSTORE_PROFILES:[DEFAULT.N...]*.;
|
DISK1:[PROFILES.DEFAULT.N...]*.;
|
| ... | ... |
PMDF_POPSTORE_PROFILES:[DEFAULT.Z...]*.;
|
DISK1:[PROFILES.DEFAULT.Z...]*.;
|
PMDF_POPSTORE_PROFILES:[DEFAULT.0...]*.;
|
DISK2:[PROFILES.DEFAULT.0...]*.;
|
| ... | ... |
PMDF_POPSTORE_PROFILES:[DEFAULT.9...]*.;
|
DISK2:[PROFILES.DEFAULT.9...]*.;
|
PMDF_POPSTORE_PROFILES:[DEFAULT.R.O.B]rob.; |
DISK1:[PROFILES.DEFAULT.R.O.B]rob. |
popstore_profile_paths file corresponding to this
mapping is shown in Example 14-6.
Example 14-5 OpenVMS
map_profile_filename Sample Subroutine |
|---|
#include <string.h>
#include "pmdf_com:popstore.h"
void map_profile_filename (uint32 version, char *def_name,
int def_len, int def_path_len,
char *new_name, int *new_len,
int max_new_len, int *new_path_len)
{
char c;
* We assume that def_name will be of the form
* PMDF_POPSTORE_PROFILES:[DEFAULT.X.Y.Z]filename.
*/
strcpy (new_name, "DISK#:[PROFILES.DEFAULT.X.Y.Z]");
c = def_name[def_path_len-6];
if ('a' <= c && c <= 'm') new_name[4] = '0';
else if ('n' <= c && c <= 'z') new_name[4] = '1';
else new_name[4] = '2';
strcat (&new_name[16], &def_name[24]);
*new_path_len = def_path_len + 8;
*new_len = strlen (new_name);
}
|
Example 14-6 OpenVMS
PMDF_TABLE:popstore_profile_paths. Sample File |
|---|
DISK0:[PROFILES...]*.;* DISK1:[PROFILES...]*.;* DISK2:[PROFILES...]*.;* |
14.3 Subroutine To Validate A Password
The popstore/msgstore has support for certain reasonableness checks on
a proposed password when a user or administrator attempts to change an
account's password. The validate_password subroutine can
be specified by sites who wish to add additional validation, such as a
dictionary or history check.
The validate_password subroutine's existence and location
are made known to the popstore/msgstore using the
VALIDATE_PASSWORD option documented in Section 3.3. When
linking this subroutine into a shared image, use link commands of the
forms given in Section 13.2.1.
The subroutine takes the form
#ifdef __VMS
#include "pmdf_com:popstore.h"
#else
#include "/pmdf/include/popstore.h"
#endif
int validate_password (password, password_len, username, username_len,
errmsg, errmsg_len, errmsg_max)
char *password;
int password_len;
char *username;
int username_len;
char *errmsg;
int *errmsg_len;
int errmsg_max;
|
password
The new password. Used for input only.password_len
The length in bytes of the new password, not including anyNULLterminator. Used for input only.username
The username of the account whose password is being changed. Used for input only.username_len
The length in bytes of the username, not including anyNULLterminator. Used for input only.errmsg
Address of a character array thatvalidate_passwordshould put an error message into if the password validation fails. The length of the message must not be longer thanerrmsg_maxbytes. Used for output only.errmsg_len
The length in bytes of the error message thatvalidate_passwordput into theerrmsgarray. Set this to 0 if no error message was placed there. Used for output only.errmsg_max
The size in bytes of the character array thaterrmsgpoints to. Used for input only.
The validate_password subroutine should return one of the following statuses:
POPSTORE_SUCCESS
If the password passed all validation checks and was accepted.POPSTORE_PWDNOTOK
If the password failed a validation check and was rejected.
A sample validate_password routine is shown in
Example 14-7 and can be found at, on OpenVMS:
PMDF_ROOT:[DOC.EXAMPLES]POPSTORE_VALIDATE_PASSWORD.C |
/pmdf/doc/examples/popstore_validate_password.c |
Example 14-7 validate_password
Sample Subroutine |
|---|
#ifdef __VMS
#include "pmdf_com:popstore.h"
#else
#include "/pmdf/include/popstore.h"
#endif
#include <string.h>
int validate_password (char *password, int password_len,
char *username, int username_len,
char *errmsg, int *errmsg_len, int errmsg_max)
{
#define MSG "Password rejected by validate_password"
(*errmsg_len) = 0;
errmsg[0] = '\0';
/* for example, reject a password of "invalid", otherwise accept */
if ((password_len == 7) &&
(password[0] == 'i') &&
(password[1] == 'n') &&
(password[2] == 'v') &&
(password[3] == 'a') &&
(password[4] == 'l') &&
(password[5] == 'i') &&
(password[6] == 'd'))
{
(*errmsg_len) = (strlen(MSG)>errmsg_max ? errmsg_max : strlen(MSG));
strncpy (errmsg, MSG, (*errmsg_len));
return (POPSTORE_PWDNOTOK);
}
else
return (POPSTORE_SUCCESS);
}
|
| Index | Contents |