mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-21 22:53:37 +00:00
builder/sysprep: Allow accounts to be locked (RHBZ#1028660).
This allows you to select both locked accounts and disabled passwords. The two are subtly different concepts. A locked account [cf. passwd -l] puts "!!" at the beginning of the shadow password field. Locking is reversible, because the "!!" can be removed, restoring the original password. Therefore "locked" acts as a flag in front of an existing selector. A disabled account has "*" in the password field. Therefore it has no password. Note that an account may be both locked and disabled, although this is probably not useful. The shadow password field will contain "!!*".
This commit is contained in:
@@ -458,7 +458,7 @@ let main () =
|
||||
pw
|
||||
| None ->
|
||||
msg (f_"Setting random root password [did you mean to use --root-password?]");
|
||||
Password.Set_random_password in
|
||||
parse_selector ~prog "random" in
|
||||
Hashtbl.replace password_map "root" pw;
|
||||
set_linux_passwords ~prog ?password_crypto g root password_map
|
||||
| _ ->
|
||||
|
||||
@@ -712,6 +712,27 @@ has approximately 120 bits of randomness.
|
||||
|
||||
This is the default.
|
||||
|
||||
=item B<--root-password> disabled
|
||||
|
||||
The root account password is disabled. This is like putting C<*>
|
||||
in the password field.
|
||||
|
||||
=item B<--root-password> locked:file:FILENAME
|
||||
|
||||
=item B<--root-password> locked:password:PASSWORD
|
||||
|
||||
=item B<--root-password> locked:random
|
||||
|
||||
The root account is locked, but a password is placed on the
|
||||
account. If first unlocked (using C<passwd -u>) then logins will
|
||||
use the given password.
|
||||
|
||||
=item B<--root-password> locked
|
||||
|
||||
=item B<--root-password> locked:disabled
|
||||
|
||||
The root account is locked I<and> password is disabled.
|
||||
|
||||
=back
|
||||
|
||||
=head3 Creating user accounts
|
||||
|
||||
@@ -22,9 +22,14 @@ open Printf
|
||||
|
||||
type password_crypto = [`MD5 | `SHA256 | `SHA512 ]
|
||||
|
||||
type password_selector =
|
||||
| Set_password of string
|
||||
| Set_random_password
|
||||
type password_selector = {
|
||||
pw_password : password;
|
||||
pw_locked : bool;
|
||||
}
|
||||
and password =
|
||||
| Password of string
|
||||
| Random_password
|
||||
| Disabled_password
|
||||
|
||||
type password_map = (string, password_selector) Hashtbl.t
|
||||
|
||||
@@ -45,12 +50,26 @@ let password_crypto_of_string ~prog = function
|
||||
exit 1
|
||||
|
||||
let rec parse_selector ~prog arg =
|
||||
match string_nsplit ":" arg with
|
||||
| [ "file"; filename ] -> Set_password (read_password_from_file filename)
|
||||
| "password" :: password -> Set_password (String.concat ":" password)
|
||||
| [ "random" ] -> Set_random_password
|
||||
parse_selector_list ~prog arg (string_nsplit ":" arg)
|
||||
|
||||
and parse_selector_list ~prog orig_arg = function
|
||||
| [ "lock"|"locked" ] ->
|
||||
{ pw_locked = true; pw_password = Disabled_password }
|
||||
| ("lock"|"locked") :: rest ->
|
||||
let pw = parse_selector_list ~prog orig_arg rest in
|
||||
{ pw with pw_locked = true }
|
||||
| [ "file"; filename ] ->
|
||||
{ pw_password = Password (read_password_from_file filename);
|
||||
pw_locked = false }
|
||||
| "password" :: password ->
|
||||
{ pw_password = Password (String.concat ":" password); pw_locked = false }
|
||||
| [ "random" ] ->
|
||||
{ pw_password = Random_password; pw_locked = false }
|
||||
| [ "disable"|"disabled" ] ->
|
||||
{ pw_password = Disabled_password; pw_locked = false }
|
||||
| _ ->
|
||||
eprintf (f_"%s: invalid password selector '%s'; see the man page.\n") prog arg;
|
||||
eprintf (f_"%s: invalid password selector '%s'; see the man page.\n")
|
||||
prog orig_arg;
|
||||
exit 1
|
||||
|
||||
and read_password_from_file filename =
|
||||
@@ -77,7 +96,8 @@ let rec set_linux_passwords ~prog ?password_crypto g root passwords =
|
||||
List.map (
|
||||
fun line ->
|
||||
try
|
||||
(* Each line is: "user:password:..."
|
||||
(* Each line is: "user:[!!]password:..."
|
||||
* !! at the front of the password field means the account is locked.
|
||||
* 'i' points to the first colon, 'j' to the second colon.
|
||||
*)
|
||||
let i = String.index line ':' in
|
||||
@@ -87,12 +107,17 @@ let rec set_linux_passwords ~prog ?password_crypto g root passwords =
|
||||
let rest = String.sub line j (String.length line - j) in
|
||||
let pwfield =
|
||||
match selector with
|
||||
| Set_password password -> encrypt password crypto
|
||||
| Set_random_password ->
|
||||
| { pw_locked = locked;
|
||||
pw_password = Password password } ->
|
||||
if locked then "!!" else "" ^ encrypt password crypto
|
||||
| { pw_locked = locked;
|
||||
pw_password = Random_password } ->
|
||||
let password = make_random_password () in
|
||||
printf (f_"Setting random password of %s to %s\n%!")
|
||||
user password;
|
||||
encrypt password crypto in
|
||||
if locked then "!!" else "" ^ encrypt password crypto
|
||||
| { pw_locked = true; pw_password = Disabled_password } -> "!!*"
|
||||
| { pw_locked = false; pw_password = Disabled_password } -> "*" in
|
||||
user ^ ":" ^ pwfield ^ rest
|
||||
with Not_found -> line
|
||||
) shadow in
|
||||
|
||||
@@ -21,9 +21,14 @@ type password_crypto = [ `MD5 | `SHA256 | `SHA512 ]
|
||||
val password_crypto_of_string : prog:string -> string -> password_crypto
|
||||
(** Parse --password-crypto parameter on command line. *)
|
||||
|
||||
type password_selector =
|
||||
| Set_password of string
|
||||
| Set_random_password
|
||||
type password_selector = {
|
||||
pw_password : password; (** The password. *)
|
||||
pw_locked : bool; (** If the account should be locked. *)
|
||||
}
|
||||
and password =
|
||||
| Password of string (** Password (literal string). *)
|
||||
| Random_password (** Choose a random password. *)
|
||||
| Disabled_password (** [*] in the password field. *)
|
||||
|
||||
val parse_selector : prog:string -> string -> password_selector
|
||||
(** Parse the selector field in --password/--root-password. Note this
|
||||
|
||||
@@ -143,6 +143,39 @@ can see the cleartext password using L<ps(1)>.
|
||||
Choose a random password, which is printed on stdout. The password
|
||||
has approximately 120 bits of randomness.
|
||||
|
||||
=item B<--password> USERNAME:disabled
|
||||
|
||||
=item B<--root-password> disabled
|
||||
|
||||
The account password is disabled. This is like putting C<*>
|
||||
in the password field.
|
||||
|
||||
=item B<--password> USERNAME:locked:file:FILENAME
|
||||
|
||||
=item B<--password> USERNAME:locked:password:PASSWORD
|
||||
|
||||
=item B<--password> USERNAME:locked:random
|
||||
|
||||
=item B<--root-password> locked:file:FILENAME
|
||||
|
||||
=item B<--root-password> locked:password:PASSWORD
|
||||
|
||||
=item B<--root-password> locked:random
|
||||
|
||||
The account is locked, but a password is placed on the
|
||||
account. If first unlocked (using C<passwd -u>) then logins will
|
||||
use the given password.
|
||||
|
||||
=item B<--password> USERNAME:locked
|
||||
|
||||
=item B<--password> USERNAME:locked:disabled
|
||||
|
||||
=item B<--root-password> locked
|
||||
|
||||
=item B<--root-password> locked:disabled
|
||||
|
||||
The account is locked I<and> password is disabled.
|
||||
|
||||
=back"
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user