summaryrefslogtreecommitdiffstats
path: root/perl-install/authentication.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/authentication.pm')
-rw-r--r--perl-install/authentication.pm220
1 files changed, 178 insertions, 42 deletions
diff --git a/perl-install/authentication.pm b/perl-install/authentication.pm
index 5e695821f..ed64289dc 100644
--- a/perl-install/authentication.pm
+++ b/perl-install/authentication.pm
@@ -3,18 +3,38 @@ package authentication; # $Id$
use common;
use any;
-
-sub kinds() {
- ('local', 'LDAP', 'NIS', 'winbind', 'AD', 'ADWIN');
+sub kinds {
+ my $no_para = @_ == 0;
+ my ($meta_class) = @_;
+ my $allow_AD = $no_para || $meta_class =~ /corporate/;
+ ('local', 'LDAP', 'NIS', 'winbind', if_($allow_AD, 'AD', 'SMBKRB'));
}
-sub kind2description {
+
+sub kind2name {
my ($kind) = @_;
- ${{ local => N("Local file\nUse local for all authentication and information user tell in local file\n"),
- LDAP => N("LDAP\nTells your computer to use LDAP for some or all authentication.\nLDAP consolidates certain types of information within your organization.\n"),
- NIS => N("NIS\nAllows you to run a group of computers in the same Network\nInformation Service domain with a common password and group file.\n"),
- winbind => N("Windows Domain\nWinbind allows a system to retrieve information about\nusers and to authenticate users by using in an Windows domain.\n "),
- AD => N("Active Directory with SFU\nKerberos is a secure system for providing network authentication services.\n"),
- ADWIN => N("Active Directory with Winbind\nKerberos is a secure system for providing network authentication services.\n") }}{$kind};
+ # Keep the following strings in sync with kind2description ones!!!
+ ${{ local => N("Local file"),
+ LDAP => N("LDAP"),
+ NIS => N("NIS"),
+ winbind => N("Windows Domain"),
+ AD => N("Active Directory with SFU"),
+ SMBKRB => N("Active Directory with Winbind") }}{$kind};
+}
+
+sub kind2description() {
+ join('',
+ map {
+ qq($_->[0]\n$_->[1]\n\n)
+ }
+ (
+ [ N("Local file:"), N("Use local for all authentication and information user tell in local file"), ],
+ [ N("LDAP:"), N("Tells your computer to use LDAP for some or all authentication. LDAP consolidates certain types of information within your organization."), ],
+ [ N("NIS:"), N("Allows you to run a group of computers in the same Network Information Service domain with a common password and group file."), ],
+ [ N("Windows Domain:"), N("Winbind allows the system to retrieve information and authenticate users in a Windows domain."), ],
+ [ N("Active Directory with SFU:"), N("Kerberos is a secure system for providing network authentication services."), ],
+ [ N("Active Directory with Winbind:"), N("Kerberos is a secure system for providing network authentication services.") ],
+ )
+ );
}
sub to_kind {
my ($authentication) = @_;
@@ -34,23 +54,22 @@ sub ask_parameters {
delete $authentication->{$_} if $_ ne $kind;
}
- if ($kind eq 'AD') {
- $authentication->{subkind} = $in->ask_from_list('', "text explaining SFU vs Winbind", [ 'SFU', 'winbind' ]) or return;
- }
-
if ($kind eq 'LDAP') {
- $authentication->{LDAP_server} ||= 'ldap.' . $netc->{DOMAINNAME};
$netc->{LDAPDOMAIN} ||= domain_to_ldap_domain($netc->{DOMAINNAME});
$in->ask_from('',
N("Authentication LDAP"),
[ { label => N("LDAP Base dn"), val => \$netc->{LDAPDOMAIN} },
{ label => N("LDAP Server"), val => \$authentication->{LDAP_server} },
]) or return;
- } elsif ($kind eq 'AD' && $authentication->{subkind} eq 'SFU') {
+ } elsif ($kind eq 'AD') {
+
$authentication->{AD_domain} ||= $netc->{DOMAINNAME};
- $authentication->{AD_server} ||= 'kerberos.' . $authentication->{AD_domain};
$authentication->{AD_users_db} ||= 'cn=users,' . domain_to_ldap_domain($authentication->{AD_domain});
- $authentication->{AD_users_idmap} ||= 'ou=idmap,' . domain_to_ldap_domain($authentication->{AD_domain});
+
+ $in->do_pkgs->install(qw(perl-Net-DNS));
+
+ my @srvs = query_srv_names($authentication->{AD_domain});
+ $authentication->{AD_server} ||= $srvs[0] if @srvs;
my %sub_kinds = my @sub_kinds = (
simple => N("simple"),
@@ -65,7 +84,8 @@ sub ask_parameters {
$in->ask_from('',
N("Authentication Active Directory"),
[ { label => N("Domain"), val => \$authentication->{AD_domain} },
- { label => N("Server"), val => \$authentication->{AD_server} },
+ #{ label => N("Server"), val => \$authentication->{AD_server} },
+ { label => N("Server"), type => 'combo', val => \$authentication->{AD_server}, list => \@srvs , not_edit => 0 },
{ label => N("LDAP users database"), val => \$authentication->{AD_users_db} },
{ label => N("Use Anonymous BIND "), val => \$anonymous, type => 'bool' },
{ label => N("LDAP user allowed to browse the Active Directory"), val => \$AD_user, disabled => sub { $anonymous } },
@@ -85,18 +105,23 @@ sub ask_parameters {
[ { label => N("NIS Domain"), val => \$netc->{NISDOMAIN} },
{ label => N("NIS Server"), val => \$authentication->{NIS_server}, list => ["broadcast"], not_edit => 0 },
]) or return;
- } elsif ($kind eq 'winbind' || $kind eq 'AD' && $authentication->{subkind} eq 'winbind') {
+ } elsif ($kind eq 'winbind' || $kind eq 'SMBKRB') {
#- maybe we should browse the network like diskdrake --smb and get the 'doze server names in a list
#- but networking isn't setup yet necessarily
- $in->ask_warn('', N("For this to work for a W2K PDC, you will probably need to have the admin run: C:\\>net localgroup \"Pre-Windows 2000 Compatible Access\" everyone /add and reboot the server.\nYou will also need the username/password of a Domain Admin to join the machine to the Windows(TM) domain.\nIf networking is not yet enabled, Drakx will attempt to join the domain after the network setup step.\nShould this setup fail for some reason and domain authentication is not working, run 'smbpasswd -j DOMAIN -U USER%%PASSWORD' using your Windows(tm) Domain, and Admin Username/Password, after system boot.\nThe command 'wbinfo -t' will test whether your authentication secrets are good."))
+ $in->ask_warn('', N("For this to work for a W2K PDC, you will probably need to have the admin run: C:\\>net localgroup \"Pre-Windows 2000 Compatible Access\" everyone /add and reboot the server.
+You will also need the username/password of a Domain Admin to join the machine to the Windows(TM) domain.
+If networking is not yet enabled, Drakx will attempt to join the domain after the network setup step.
+Should this setup fail for some reason and domain authentication is not working, run 'smbpasswd -j DOMAIN -U USER%%PASSWORD' using your Windows(tm) Domain, and Admin Username/Password, after system boot.
+The command 'wbinfo -t' will test whether your authentication secrets are good."))
if $kind eq 'winbind';
- $authentication->{AD_domain} ||= $netc->{DOMAINNAME} if $kind eq 'AD';
- $authentication->{AD_users_idmap} ||= 'ou=idmap,' . domain_to_ldap_domain($authentication->{AD_domain}) if $kind eq 'AD';
+ $authentication->{AD_domain} ||= $netc->{DOMAINNAME} if $kind eq 'SMBKRB';
+ $authentication->{AD_users_idmap} ||= 'ou=idmap,' . domain_to_ldap_domain($authentication->{AD_domain}) if $kind eq 'SMBKRB';
$netc->{WINDOMAIN} ||= $netc->{DOMAINNAME};
+ my $anonymous;
$in->ask_from('',
- $kind eq 'AD' ? N("Authentication Active Directory") : N("Authentication Windows Domain"),
- [ if_($kind eq 'AD',
+ $kind eq 'SMBKRB' ? N("Authentication Active Directory") : N("Authentication Windows Domain"),
+ [ if_($kind eq 'SMBKRB',
{ label => N("Domain"), val => \$authentication->{AD_domain} }
),
{ label => N("Windows Domain"), val => \$netc->{WINDOMAIN} },
@@ -110,8 +135,45 @@ sub ask_parameters {
1;
}
+sub ask_root_password_and_authentication {
+ my ($in, $netc, $superuser, $authentication, $meta_class, $security) = @_;
+
+ my $kind = to_kind($authentication);
+
+ $in->ask_from_({
+ title => N("Set root password and network authentication methods"),
+ messages => N("Set root password"),
+ advanced_messages => kind2description(),
+ interactive_help_id => "setRootPassword",
+ cancel => ($security <= 2 ?
+ #-PO: keep this short or else the buttons will not fit in the window
+ N("No password") : ''),
+ focus_first => 1,
+ callbacks => {
+ complete => sub {
+ $superuser->{password} eq $superuser->{password2} or $in->ask_warn('', [ N("The passwords do not match"), N("Please try again") ]), return 1,0;
+ length $superuser->{password} < 2 * $security
+ and $in->ask_warn('', N("This password is too short (it must be at least %d characters long)", 2 * $security)), return 1,0;
+ return 0;
+ } } }, [
+{ label => N("Password"), val => \$superuser->{password}, hidden => 1 },
+{ label => N("Password (again)"), val => \$superuser->{password2}, hidden => 1 },
+{ label => N("Authentication"), val => \$kind, type => 'list', list => [ authentication::kinds($meta_class) ], format => \&authentication::kind2name, advanced => 1 },
+ ]) or delete $superuser->{password};
+
+ ask_parameters($in, $netc, $authentication, $kind) or goto &ask_root_password_and_authentication;
+}
+
+
+sub get() {
+ my $system_auth = cat_("/etc/pam.d/system-auth");
+ { md5 => $system_auth =~ /md5/, shadow => $system_auth =~ /shadow/ };
+}
+
sub set {
- my ($in, $netc, $authentication, $when_network_is_up) = @_;
+ my ($in, $netc, $authentication, $o_when_network_is_up) = @_;
+
+ my $when_network_is_up = $o_when_network_is_up || sub { my ($f) = @_; $f->() };
any::enableShadow() if $authentication->{shadow};
@@ -133,15 +195,14 @@ sub set {
update_ldap_conf(
host => $authentication->{LDAP_server},
base => $domain,
- port => 636,
- ssl => 'on',
- nss_base_shadow => "ou=People,$domain",
- nss_base_passwd => "ou=People,$domain",
- nss_base_group => "ou=Group,$domain",
+ nss_base_shadow => $domain."?sub",
+ nss_base_passwd => $domain."?sub",
+ nss_base_group => $domain."?sub",
);
- } elsif ($kind eq 'AD' && $authentication->{subkind} eq 'SFU') {
+ } elsif ($kind eq 'AD') {
$in->do_pkgs->install(qw(nss_ldap pam_krb5 libsasl2-plug-gssapi));
-
+ my $port = "389";
+
set_nsswitch_priority('ldap');
set_pam_authentication('krb5');
@@ -153,6 +214,12 @@ sub set {
kerberos => 'off',
}->{$authentication->{sub_kind}};
+ if ($ssl eq 'on') {
+ $port = '636';
+ };
+
+
+
update_ldap_conf(
host => $authentication->{AD_server},
base => domain_to_ldap_domain($authentication->{AD_domain}),
@@ -162,6 +229,7 @@ sub set {
ssl => $ssl,
sasl_mech => $authentication->{sub_kind} eq 'kerberos' ? 'GSSAPI' : '',
+ port => $port,
binddn => $authentication->{AD_user},
bindpw => $authentication->{AD_password},
@@ -171,6 +239,14 @@ sub set {
shadowAccount => 'User',
posixGroup => 'Group',
),
+
+
+ scope => 'sub',
+ pam_login_attribute => 'sAMAccountName',
+ pam_filter => 'objectclass=User',
+ pam_password => 'ad',
+
+
(map_each { "nss_map_attribute_$::a" => $::b }
uid => 'sAMAccountName',
uidNumber => 'msSFU30UidNumber',
@@ -179,7 +255,7 @@ sub set {
uniqueMember => 'member',
userPassword => 'msSFU30Password',
homeDirectory => 'msSFU30HomeDirectory',
- LoginShell => 'msSFU30LoginShell',
+ loginShell => 'msSFU30LoginShell',
gecos => 'name',
),
);
@@ -225,26 +301,29 @@ sub set {
#- defer running smbpassword until the network is up
$when_network_is_up->(sub {
- run_program::rooted($::prefix, 'smbpasswd', '-j', $domain, '-U', $authentication->{winuser} . '%' . $authentication->{winpass});
+ run_program::rooted($::prefix, 'net', 'join', $domain, '-U', $authentication->{winuser} . '%' . $authentication->{winpass});
});
- } elsif ($kind eq 'AD' && $authentication->{subkind} eq 'winbind') {
-
+ } elsif ($kind eq 'SMBKRB') {
+ $authentication->{AD_server} ||= 'ads.' . $authentication->{AD_domain};
my $domain = uc $netc->{WINDOMAIN};
my $realm = $authentication->{AD_domain};
configure_krb5_for_AD($authentication);
- $in->do_pkgs->install('samba-winbind', 'pam_krb5');
+ $in->do_pkgs->install('samba-winbind', 'pam_krb5', 'samba-server', 'samba-client');
set_nsswitch_priority('winbind');
set_pam_authentication('winbind');
-
+
require network::smb;
network::smb::write_smb_ads_conf($domain,$realm);
run_program::rooted($::prefix, "chkconfig", "--level", "35", "winbind", "on");
mkdir_p("$::prefix/home/$domain");
+ run_program::rooted($::prefix, 'net', 'time', 'set', '-S', $authentication->{AD_server});
+ run_program::rooted($::prefix, 'service', 'smb', 'restart');
+ run_program::rooted($::prefix, 'service', 'winbind', 'restart');
$when_network_is_up->(sub {
- run_program::rooted($::prefix, 'net','ads','join', '-U', $authentication->{winuser} . '%' . $authentication->{winpass});
+ run_program::rooted($::prefix, 'net', 'ads', 'join', '-U', $authentication->{winuser} . '%' . $authentication->{winpass});
});
}
}
@@ -284,7 +363,7 @@ sub set_pam_authentication {
password => [ intersection(\@authentication_kinds, [ 'ldap', 'krb5' ]) ],
);
my %before_first = (
- session => intersection(\@authentication_kinds, [ 'winbind', 'krb5' ]) ? pam_format_line('session', 'optional', 'pam_mkhomedir', 'skel=/etc/skel/', 'umask=0022') : '',
+ session => intersection(\@authentication_kinds, [ 'winbind', 'krb5','ldap' ]) ? pam_format_line('session', 'optional', 'pam_mkhomedir', 'skel=/etc/skel/', 'umask=0022') : '',
);
my %after_deny = (
session => member('krb5', @authentication_kinds) ? pam_format_line('session', 'optional', 'pam_krb5') : '',
@@ -299,7 +378,7 @@ sub set_pam_authentication {
}
if ($module eq 'pam_unix' && $special{$type} && @{$special{$type}}) {
my @para_for_last =
- $type eq 'auth' ? qw(likeauth nullok use_first_pass) :
+ $type eq 'auth' ? qw(use_first_pass) :
$type eq 'account' ? qw(use_first_pass) : @{[]};
@para = difference2(\@para, \@para_for_last);
@@ -485,5 +564,62 @@ sub krb5_conf_update {
MDK::Common::File::output($file, $s);
}
+
+sub query_srv_names {
+ my ($domain) = @_;
+
+ eval { require Net::DNS; 1 } or return;
+ my $res = Net::DNS::Resolver->new;
+ my $query = $res->query("_ldap._tcp.$domain", 'srv') or return;
+ map { $_->target } $query->answer;
+}
+
+sub crypt {
+ my ($password, $md5) = @_;
+ crypt($password, $md5 ? '$1$' . salt(8) : salt(2));
+}
+
+sub user_crypted_passwd {
+ my ($u, $isMD5) = @_;
+ $u->{password} ? &crypt($u->{password}, $isMD5) : $u->{pw} || '';
+}
+
+sub set_root_passwd {
+ my ($superuser, $authentication) = @_;
+ $superuser->{name} = 'root';
+ write_passwd_user($superuser, $authentication->{md5});
+ delete $superuser->{name};
+}
+
+sub write_passwd_user {
+ my ($u, $isMD5) = @_;
+
+ $u->{pw} = user_crypted_passwd($u, $isMD5);
+ $u->{shell} ||= '/bin/bash';
+
+ substInFile {
+ my $l = unpack_passwd($_);
+ if ($l->{name} eq $u->{name}) {
+ add2hash_($u, $l);
+ $_ = pack_passwd($u);
+ $u = {};
+ }
+ if (eof && $u->{name}) {
+ $_ .= pack_passwd($u);
+ }
+ } "$::prefix/etc/passwd";
+}
+
+my @etc_pass_fields = qw(name pw uid gid realname home shell);
+sub unpack_passwd {
+ my ($l) = @_;
+ my %l; @l{@etc_pass_fields} = split ':', chomp_($l);
+ \%l;
+}
+sub pack_passwd {
+ my ($l) = @_;
+ join(':', @$l{@etc_pass_fields}) . "\n";
+}
+
1;