Documented mailbox quotas
Showing
1 changed file
with
199 additions
and
13 deletions
... | @@ -268,24 +268,40 @@ name of @acronym{pam} service to be used when authenticating. | ... | @@ -268,24 +268,40 @@ name of @acronym{pam} service to be used when authenticating. |
268 | The following options exist in this group if the package was configured | 268 | The following options exist in this group if the package was configured |
269 | with @option{--enable-sql} option. They take effect only if the | 269 | with @option{--enable-sql} option. They take effect only if the |
270 | @samp{sql} module is used in authentication and/or authorization. | 270 | @samp{sql} module is used in authentication and/or authorization. |
271 | Currently only MySQL is supported. | ||
272 | 271 | ||
273 | @table @option | 272 | @table @option |
274 | @item --sql-getpwnam @var{query} | 273 | @item --sql-interface @var{iface} |
275 | @acronym{sql} query to retrieve a passwd entry based on username | 274 | Specify @sc{sql} interface to use. @var{Iface} is either @samp{mysql} |
276 | @item --sql-getpwuid @var{query} | 275 | or @samp{postgres}. This allows to select @sc{sql} subsystem on |
277 | @item --sql-getpass @var{query} | 276 | runtime if @code{mailutils} was compiled with support for several |
278 | @acronym{sql} query to retrieve a password from the database | 277 | @sc{sql} drivers. |
278 | |||
279 | If this option is omitted, @code{mailutils} will use the first | ||
280 | available @sc{sql} driver. | ||
281 | |||
279 | @item --sql-host @var{name} | 282 | @item --sql-host @var{name} |
280 | Name or IP of MySQL server to connect to. | 283 | Name or IP of MySQL server to connect to. |
284 | |||
281 | @item --sql-user @var{name} | 285 | @item --sql-user @var{name} |
282 | @acronym{sql} user name | 286 | @acronym{sql} user name |
287 | |||
283 | @item --sql-passwd @var{string} | 288 | @item --sql-passwd @var{string} |
284 | @acronym{sql} connection password | 289 | @acronym{sql} connection password |
290 | |||
285 | @item --sql-db @var{string} | 291 | @item --sql-db @var{string} |
286 | Name of the database to connect to. | 292 | Name of the database to connect to. |
293 | |||
287 | @item --sql-port @var{number} | 294 | @item --sql-port @var{number} |
288 | Port to use | 295 | Port to use |
296 | |||
297 | @item --sql-getpwnam @var{query} | ||
298 | @acronym{sql} query to retrieve a passwd entry based on username | ||
299 | |||
300 | @item --sql-getpwuid @var{query} | ||
301 | @acronym{sql} query to retrieve a passwd entry based on user ID | ||
302 | |||
303 | @item --sql-getpass @var{query} | ||
304 | @acronym{sql} query to retrieve a password from the database | ||
289 | @end table | 305 | @end table |
290 | 306 | ||
291 | @node encryption | 307 | @node encryption |
... | @@ -2856,18 +2872,27 @@ not specified, @command{mail.local} first looks into the first line | ... | @@ -2856,18 +2872,27 @@ not specified, @command{mail.local} first looks into the first line |
2856 | from the standard input. If it starts with @samp{From }, it is assumed | 2872 | from the standard input. If it starts with @samp{From }, it is assumed |
2857 | to contain a valid envelope. If it does not, @command{mail.local} | 2873 | to contain a valid envelope. If it does not, @command{mail.local} |
2858 | creates the envelope by using current user name and date. | 2874 | creates the envelope by using current user name and date. |
2875 | |||
2859 | @item -h | 2876 | @item -h |
2860 | @itemx --help | 2877 | @itemx --help |
2861 | Display this help and exit. | 2878 | Display usage summary and exit. |
2879 | |||
2862 | @item -L | 2880 | @item -L |
2863 | @itemx --license | 2881 | @itemx --license |
2864 | Display @sc{gnu} General Public License and exit. | 2882 | Display @sc{gnu} General Public License and exit. |
2883 | |||
2865 | @item -m @var{path} | 2884 | @item -m @var{path} |
2866 | @itemx --mail-spool @var{path} | 2885 | @itemx --mail-spool @var{path} |
2867 | Specify path to mailspool directory. | 2886 | Specify path to mailspool directory. |
2887 | |||
2868 | @item -q | 2888 | @item -q |
2869 | @itemx --quota-db @var{file} | 2889 | @itemx --quota-db @var{file} |
2870 | Specify path to mailbox quota database (@pxref{Mailbox Quotas}). | 2890 | Specify path to DBM mailbox quota database (@pxref{Mailbox Quotas}). |
2891 | |||
2892 | @item --quota-query | ||
2893 | Specify SQL query that should be used to obtain user mailbox | ||
2894 | quotas from the SQL database (@pxref{Mailbox Quotas}). | ||
2895 | |||
2871 | @item -s @var{pattern} | 2896 | @item -s @var{pattern} |
2872 | @itemx --source @var{pattern} | 2897 | @itemx --source @var{pattern} |
2873 | Set name pattern for user-defined mail filters written in Scheme | 2898 | Set name pattern for user-defined mail filters written in Scheme |
... | @@ -2968,7 +2993,7 @@ Mlocal, P=/usr/local/libexec/mail.local, | ... | @@ -2968,7 +2993,7 @@ Mlocal, P=/usr/local/libexec/mail.local, |
2968 | F=lsDFMAw5:/|@@qSPfhn9, | 2993 | F=lsDFMAw5:/|@@qSPfhn9, |
2969 | S=EnvFromL/HdrFromL, R=EnvToL/HdrToL, | 2994 | S=EnvFromL/HdrFromL, R=EnvToL/HdrToL, |
2970 | T=DNS/RFC822/X-Unix, | 2995 | T=DNS/RFC822/X-Unix, |
2971 | A=mail -s %h/.filter.scm -q /etc/mail/userquota $u | 2996 | A=mail $u |
2972 | @end smallexample | 2997 | @end smallexample |
2973 | 2998 | ||
2974 | To define local mailer in @samp{mc} source file, it will suffice to | 2999 | To define local mailer in @samp{mc} source file, it will suffice to |
... | @@ -2976,8 +3001,7 @@ set: | ... | @@ -2976,8 +3001,7 @@ set: |
2976 | 3001 | ||
2977 | @smallexample | 3002 | @smallexample |
2978 | define(`LOCAL_MAILER_PATH', `/usr/local/libexec/mail.local') | 3003 | define(`LOCAL_MAILER_PATH', `/usr/local/libexec/mail.local') |
2979 | define(`LOCAL_MAILER_ARGS', | 3004 | define(`LOCAL_MAILER_ARGS', `mail $u') |
2980 | `mail -s %h/.filter.scm -q /etc/mail/userquota $u') | ||
2981 | @end smallexample | 3005 | @end smallexample |
2982 | 3006 | ||
2983 | @node Exim | 3007 | @node Exim |
... | @@ -2991,8 +3015,7 @@ and director in @file{exim.conf}: | ... | @@ -2991,8 +3015,7 @@ and director in @file{exim.conf}: |
2991 | # transport | 3015 | # transport |
2992 | mail_local_pipe: | 3016 | mail_local_pipe: |
2993 | driver = pipe | 3017 | driver = pipe |
2994 | command = /usr/local/libexec/mail.local -s %h/.filter.scm \ | 3018 | command = /usr/local/libexec/mail.local $local_part |
2995 | -q /etc/mail/userquota $local_part | ||
2996 | return_path_add | 3019 | return_path_add |
2997 | delivery_date_add | 3020 | delivery_date_add |
2998 | envelope_to_add | 3021 | envelope_to_add |
... | @@ -3006,6 +3029,169 @@ mail_local: | ... | @@ -3006,6 +3029,169 @@ mail_local: |
3006 | @node Mailbox Quotas | 3029 | @node Mailbox Quotas |
3007 | @subsection Setting up Mailbox Quotas | 3030 | @subsection Setting up Mailbox Quotas |
3008 | 3031 | ||
3032 | Sometimes it is necessary to limit the maximum size of a user's | ||
3033 | mailbox. Such maximum size is called @dfn{mailbox quota} for this | ||
3034 | user. | ||
3035 | |||
3036 | When delivering a message, @command{mail.local} first cheks if | ||
3037 | the mailbox quota is specified for the recipient. If so, | ||
3038 | @command{mail.local} computes the difference between the quota | ||
3039 | value and the actual size of the recipient's mailbox. This difference | ||
3040 | represents the maximum size of the message the receipient's mailbox is | ||
3041 | able to accomodate. Let's call it @var{msize}. Depending on its value, | ||
3042 | @command{mail.local} takes decision on whether to deliver the message. | ||
3043 | There are three possible cases: | ||
3044 | |||
3045 | @enumerate 1 | ||
3046 | @item @var{msize} equals zero. This means that the mailbox size has | ||
3047 | reached its limit). In this case the message is not delivered and | ||
3048 | the sender receives following notification message: | ||
3049 | |||
3050 | @smallexample | ||
3051 | @var{user}: mailbox quota exceeded for this recipient | ||
3052 | @end smallexample | ||
3053 | |||
3054 | @item @var{msize} is less than the size of the message | ||
3055 | @command{mail.local} is about to deliver. In this case the message is | ||
3056 | not delivered and the sender receives following notification message: | ||
3057 | |||
3058 | @smallexample | ||
3059 | @var{user}: message would exceed maximum mailbox size for this recipient | ||
3060 | @end smallexample | ||
3061 | |||
3062 | @item @var{msize} is greater than or equal to the size of the | ||
3063 | message. In this case @command{mail.local} does deliver the message. | ||
3064 | @end enumerate | ||
3065 | |||
3066 | Version @value{VERSION} of @sc{gnu} mailutils is able to retrieve | ||
3067 | mailbox quotas from a @sc{dbm} or @sc{sql} database. | ||
3068 | |||
3069 | @menu | ||
3070 | * DBM Quotas:: Keeping Quotas in DBM Database. | ||
3071 | * SQL Quotas:: Keeping Quotas in SQL Database. | ||
3072 | @end menu | ||
3073 | |||
3074 | @node DBM Quotas | ||
3075 | @subsubsection Keeping Quotas in DBM Database | ||
3076 | |||
3077 | To use the @sc{dbm} quota database, your copy of @code{mailutils} must | ||
3078 | be compiled with @sc{dbm} support (one of @option{--with-gdbm}, | ||
3079 | @option{--with-db2}, @option{--with-ndbm}, @option{--with-dbm} options | ||
3080 | to @code{configure}). Examine the of | ||
3081 | @command{mail.local --show-config-options} if not sure. | ||
3082 | |||
3083 | The quota database should have the following structure: | ||
3084 | |||
3085 | @table @asis | ||
3086 | @item Key | ||
3087 | Key represents the user name. Special key @samp{DEFAULT} means default | ||
3088 | quota value, i.e. the one to be used if the user is not explicitely | ||
3089 | listed in the database. | ||
3090 | |||
3091 | @item Value | ||
3092 | The mailbox quota for this user. If it is a number, it represents the | ||
3093 | maximum mailbox size in bytes. A number may optionally be followed by | ||
3094 | @samp{kb} or @samp{mb}, meaning kilobytes and megabytes, respectively. | ||
3095 | |||
3096 | A special value @samp{NONE} means no mailbox size limitation for this user. | ||
3097 | @end table | ||
3098 | |||
3099 | Here is an example of a valid quota database | ||
3100 | |||
3101 | @smallexample | ||
3102 | # Default quota value: | ||
3103 | DEFAULT 5mb | ||
3104 | |||
3105 | # Following users have unlimited mailbox size | ||
3106 | root NONE | ||
3107 | smith NONE | ||
3108 | |||
3109 | # Rest of users | ||
3110 | plog 26214400 | ||
3111 | karin 10mB | ||
3112 | @end smallexample | ||
3113 | |||
3114 | To use the @sc{dbm} database, specify its full name using @option{-q} | ||
3115 | or @samp{--quota-db} in the invocation of @command{mail.local}. For | ||
3116 | example, in @command{sendmail} @code{.mc} file: | ||
3117 | |||
3118 | @smallexample | ||
3119 | define(`LOCAL_MAILER_PATH', `/usr/local/libexec/mail.local') | ||
3120 | define(`LOCAL_MAILER_ARGS', `mail -q /etc/mail/quota.db $u') | ||
3121 | @end smallexample | ||
3122 | |||
3123 | @node SQL Quotas | ||
3124 | @subsubsection Keeping Quotas in SQL Database | ||
3125 | |||
3126 | Option @option{--quota-query} allows to specify a special query to | ||
3127 | retrieve the quota from the database. Currently (as of mailutils | ||
3128 | version @value{VERSION}) it is assumed that this table can be accessed | ||
3129 | using the same credentials as @sc{sql} authentication tables | ||
3130 | (@xref{daemon}, for the detailed discussion of @option{--sql-} options). | ||
3131 | |||
3132 | For example, suppose you have the following quota table: | ||
3133 | |||
3134 | @smallexample | ||
3135 | create table mailbox_quota ( | ||
3136 | user_name varchar(32) binary not null, | ||
3137 | quota int, | ||
3138 | unique (user_name) | ||
3139 | ); | ||
3140 | @end smallexample | ||
3141 | |||
3142 | @noindent | ||
3143 | |||
3144 | To retrieve the quota for user @code{%u} you may then use the | ||
3145 | following query: | ||
3146 | |||
3147 | @smallexample | ||
3148 | SELECT quota | ||
3149 | FROM mailbox_quota | ||
3150 | WHERE user_name='%u' | ||
3151 | @end smallexample | ||
3152 | |||
3153 | There is no special provisions for specifying group quotas, similar to | ||
3154 | @samp{DEFAULT} in @sc{dbm} databases. This is because group quotas can | ||
3155 | easily be implemented using @sc{sql} language. @command{Mail.local} | ||
3156 | always uses the first tuple from the set returned by mailbox quota | ||
3157 | query. So, you may add a special entry to the @code{mailbox_quota} | ||
3158 | table that would keep the group quota. For the following discussion, | ||
3159 | it is important that the @code{user_name} column for this entry be | ||
3160 | lexicographically less than any other user name in the table. Let's | ||
3161 | suppose the group quota name is @samp{00DEFAULT}. Then the following | ||
3162 | query: | ||
3163 | |||
3164 | @smallexample | ||
3165 | SELECT quota | ||
3166 | FROM mailbox_quota | ||
3167 | WHERE user_name IN ('%u','00DEFAULT') | ||
3168 | ORDER BY user_name DESC | ||
3169 | @end smallexample | ||
3170 | |||
3171 | @noindent | ||
3172 | will return two tuples if user @code{%u} is found in | ||
3173 | @code{mailbox_quota}. Due to @code{ORDER} statement, the first tuple | ||
3174 | will contain the quota for the user, which will be used by | ||
3175 | @command{mail.local}. On the other hand, if user name @code{%u} is not | ||
3176 | present in the table, the above query will return a single tuple | ||
3177 | containing the group quota. | ||
3178 | |||
3179 | To summarize this, here is a working @file{mailutils.rc} entry for | ||
3180 | @command{mail.local}: | ||
3181 | |||
3182 | @smallexample | ||
3183 | :mail.local \ | ||
3184 | --sql-db MAILAUTH \ | ||
3185 | --sql-host some.host.net \ | ||
3186 | --sql-user mail.local \ | ||
3187 | --sql-passwd guessme \ | ||
3188 | --quota-query "SELECT quota \ | ||
3189 | FROM mailbox_quota \ | ||
3190 | WHERE user_name IN ('%u','00DEFAULT') \ | ||
3191 | ORDER BY user_name DESC" | ||
3192 | @end smallexample | ||
3193 | |||
3194 | |||
3009 | @node Sieve Filters | 3195 | @node Sieve Filters |
3010 | @subsection Implementing User-defined Sieve Mail Filters | 3196 | @subsection Implementing User-defined Sieve Mail Filters |
3011 | 3197 | ... | ... |
-
Please register or sign in to post a comment