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_VERSION
option. Formap_profile_filename
, this argument is the current value of thePROFILE_FILENAME_VERSION
option. Used for input only.def_name
The default file specification including the full path and filename. This string isNULL
terminated. Used for input only.def_len
The length in bytes of the default file specification. The length does not include anyNULL
terminator. 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_len
bytes ofdef_name
is 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 beNULL
terminated. 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. Thedefault
directory name in the path should not be removed---it is part of the popstore's user domain naming system.default
is the default user domain. Used for output only.new_len
The length in bytes, not including theNULL
terminator, of the new file specification. Used for output only.max_new_len
Maximum length in bytes ofnew_name
, not including a trailingNULL
terminator. The name passed back innew_name
can not exceed this length. Used for input only. Note that the following relationship will always hold:
def_path_len
<= 252 bytes <=max_new_len
new_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 anyNULL
terminator. 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 anyNULL
terminator. Used for input only.errmsg
Address of a character array thatvalidate_password
should put an error message into if the password validation fails. The length of the message must not be longer thanerrmsg_max
bytes. Used for output only.errmsg_len
The length in bytes of the error message thatvalidate_password
put into theerrmsg
array. 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 thaterrmsg
points 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 |