password quality script aka --with-cracklib replacement

Martin Pool mbp at
Wed Feb 12 04:50:51 GMT 2003

On 11 Feb 2003, Pierre Belanger <belanger at> wrote:

> What is it? I have my own comments at the end ...
> From the documentation I wrote (even if I'm French I think it's not
> that bad!?!?!?):

This looks good to me.

Would it be possible to do this as a PAM module called by Samba?
(Possibly not, or not appropriate, but I thought I'd ask.)

Presumably if the script is set in the smb.conf but can't be run then
Samba ought to "fail closed" and deny the change request.

Is there any need to allow changes by the administrator to bypass this

>           Full path to the script that  will  be  called  when  a
>           request for change password is received. It will be run
>           by smbd as non-ROOT.
>           The script is responsible to accept or refuse  the  new
>           password  based on its own rules. As an example, it can
>           be a script refusing a weak password based  on  a  dic-
>           tionary word.

OK, that sounds good.

For things like preventing password reuse the script will need to keep
a database of (probably hashed) old passwords.  It's probably best to
keep this functionality out of smbd.

Are there permissions problems in the script maintaining state such as
this?  The interface ought to define whether the script will be run
under the uid of the person whose password is being changed.  Perhaps
some scripts will need to be setgid to store information in a file not
accessible to the user -- after all the point of this is to impose
restrictions on what the user can do.

In fact, it seems to me that to be really secure, this operation *must
not* be done under the uid whose password is being changed: enforcing
security from a process under the control of that user is very weak.

>           Samba back end communicates with the  password  quality
>           program  by  writing data to its STDIN and reading data
>           from its STDOUT.  Samba  writes  a  block  of  data  in
>           "Field:value\n"  terminated by a ".\n" at the beginning
>           of a new line.
>           1) smbd to ---> Password quality script "STDIN"
>                     Version:smbd-version-string\n
>                     Username:username\n
>                     Fullname:fullname\n
>                     Password:new-password\n
>                     .\n

This seems conceptually good, but I have a few comments on the format.

The interface definition ought to say that the strings are sent in

Using \n for a delimiter seems like asking for trouble; such as a
fullname or new password containing that character.  I'd suggest \0.
I don't think this has to be a human-readable protocol.

I am not sure that the "headings" like "Version:" really add much.  If
you're going to use something like RFC822 then it ought to be a closer
match, with a space after the colon.  Similarly, rather than the final
dot, why not close the connection?

Perhaps it would be better to specify the "protocol version", rather
than the smbd version?  i.e. just send "Version: 1" at first.  A
script written today doesn't know what future version numbers will be.

Personally I would use something like a tdbpacked string, which avoids
worries about strange characters or string parsing, and is easy to
handle in C, Perl, and Python.

>                     NTStatus:ntstatus-string\n
>                     Result:result-string\n
>                     .\n
>           The "ntstatus-string" value  must  used  one  the  pre-
>           defined NTSTATUS (nterr.h) values. In this context:
>           NT_STATUS_OK # New password accepted
>           NT_STATUS_ACCESS_DENIED # Error occured in the script
>           NT_STATUS_PASSWORD_RESTRICTION # Too short,  weak, etc.

I think you should send the hex value, not the string.

>           The "result-string" value is used to  provide  informa-
>           tion (debug info) to smbd. For examples:
>                     NTStatus:NT_STATUS_PASSWORD_RESTRICTION\n
>                     Result:Password is based on dictionary word\n
>                     or
>                     NTStatus:NT_STATUS_OK\n
>                     Result:New password is accepted\n
>           smbd will always return an error to the client and does
>           not  change  the  current  password unless the NTStatus
>           value is equal to "NT_STATUS_OK" and the exit status of
>           the script equal to 0.
>           Default: password quality script = <empty string>
>           Example:      password      quality      script       =
>           /usr/local/samba/sbin/

> Do you wonder why sending the "smbd-version-string"? Perhaps
> in the future a new NTSTATUS will be added. The only way for the
> external program to know if it can use the new value is by
> knowing the version of Samba! There are other possible examples.

If you send the hex value, then it doesn't matter if Samba understands
the code or not -- it can just pass it back to the client.  Anyhow,
I don't think it's likely that the script authors will know exactly
which versions of smbd support which codes.

> [Q] What do we do with the fullname? We don't care? What if it's not
> available ('\0')? Do we write to the external program an empty string
> like this  ->Fullname:\n<-  or we just don't send the fullname field
> to the external program or perhaps something like "Fullname:Unknown\n"?
> I think -- either we always send something (Unknown when it's empty)
> or we just don't send it. I think it's less confusing for everyone
> is we write in the documentation if fullname is not known, we write
> "Unknown" (or empty or NULL!).

Please don't send the string "Unknown"; that loses information.  If
it's null, just send an empty string.

> Let me know what you think and/or other ideas.

Hope that helps.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url :

More information about the samba-technical mailing list