ACC SHELL

Path : /usr/share/YaST2/modules/
File Upload :
Current File : //usr/share/YaST2/modules/SambaNetJoin.pm

#! /usr/bin/perl
# File:		modules/SambaNetJoin.pm
# Package:	Configuration of samba-server
# Summary:	Manage samba configuration data (smb.conf).
# Authors:	Martin Lazar <mlazar@suse.cz>
#
# $Id: SambaNetJoin.pm 58415 2009-08-21 10:02:44Z jsuchome $
#

package SambaNetJoin;

use strict;
use Data::Dumper;

use YaST::YCP qw(:LOGGING);
use YaPI;

textdomain "samba-client";
our %TYPEINFO;

YaST::YCP::Import("SCR");
YaST::YCP::Import("SambaConfig");
YaST::YCP::Import("SambaAD");
YaST::YCP::Import("String");

my %TestJoinCache;

# Check if this host is a member of a given domain.
#
# @param domain  a name of the domain to check
# @param force  do force check (otherwise use cache)
# @return boolean  true if the host is a member, false if not, nil on error (not possible to find out)
BEGIN{$TYPEINFO{Test}=["function","boolean","string"]}
sub Test {
    my ($self, $domain) = @_;
    
    return $TestJoinCache{$domain} if defined $TestJoinCache{$domain};

    my $protocol	= SambaAD->ADS () ne "" ? "ads" : "rpc";
    my $netbios_name 	= SambaConfig->GlobalGetStr("netbios name", undef);
    my $conf_file	= SCR->Read (".target.tmpdir")."/smb.conf";
    my $include		= "";
    $include	= "\n\tinclude = /etc/samba/dhcp.conf" if (SCR->Read (".sysconfig.network.dhcp.DHCLIENT_MODIFY_SMB_CONF") eq "yes");

    if ($protocol eq "ads") {
	my $realm	= SambaAD->Realm ();
	SCR->Write (".target.string", $conf_file, "[global]$include\n\trealm = $realm\n\tsecurity = ADS\n\tworkgroup = $domain\n");
    }
    else {
	SCR->Write (".target.string", $conf_file, "[global]$include\n\tsecurity = domain\n\tworkgroup = $domain\n");
    }

    # FIXME -P is probably wrong, but suppresses password prompt
    my $cmd = "LANG=C net $protocol testjoin -s $conf_file -P";
    if ($protocol ne "ads") {
	$cmd = $cmd." -w '$domain'" . ($netbios_name?" -n '$netbios_name'":"");
    }
    my $res = SCR->Execute(".target.bash_output", $cmd);
    y2internal("$cmd => ".Dumper($res));
    return $TestJoinCache{$domain} = ($res && defined $res->{exit} && $res->{exit}==0);
}

# Joins the host into a given domain. If user is provided, it will use
# the user and password for joining. If the user is nil, joining will
# be done anonymously.
#
# Attention: It will write the configuration for domain before settings the password
#
# @param domain	a name of a domain to be joined
# @param join_level	level of a domain membership when joining ("member", "bdc" or "pdc")
# @param user		username to be used for joining, or nil for anonymous
# @param passwd		password for the user
# @param machine	machine account to join into (fate 301320)
# @return string	an error message or nil if successful
BEGIN{$TYPEINFO{Join}=[
    "function","string","string","string","string","string","string"]}
sub Join {
    my ($self, $domain, $join_level, $user, $passwd, $machine) = @_;
    
    my $netbios_name	= SambaConfig->GlobalGetStr("netbios name", undef);
    my $server		= SambaAD->ADS ();
    my $protocol	= $server ne "" ? "ads" : "rpc";
    my $tmpdir	= SCR->Read (".target.tmpdir");
    my $conf_file	= $tmpdir."/smb.conf";
    my $cmd		= "";

    my $include		= "";
    # bnc#520648 (DHCP may know WINS server address)
    $include	= "\n\tinclude = /etc/samba/dhcp.conf" if (SCR->Read (".sysconfig.network.dhcp.DHCLIENT_MODIFY_SMB_CONF") eq "yes");

    if ($protocol eq "ads") {
	my $krb_file	= $tmpdir."/krb5.conf";
	my $realm	= SambaAD->Realm ();
	SCR->Write (".target.string", $conf_file, "[global]$include\n\trealm = $realm\n\tsecurity = ADS\n\tworkgroup = $domain\n");
	$cmd		= "KRB5_CONFIG=$krb_file ";
	SCR->Write (".target.string", $krb_file, "[realms]\n\t$realm = {\n\tkdc = $server\n\t}\n");
    }
    else {
	SCR->Write (".target.string", $conf_file, "[global]$include\n\tsecurity = domain\n\tworkgroup = $domain\n");
    }

    $cmd = $cmd."net $protocol join "
	. ($protocol ne "ads" ? lc($join_level||"") : "")
	. ($protocol ne "ads" ? " -w '$domain'" : "")
	. " -s $conf_file"
	. (($protocol ne "ads" && $netbios_name)?" -n '$netbios_name'":"")
	. " -U '" . String->Quote ($user) . "%" . String->Quote ($passwd) . "'";

    if ($machine) {
	$machine	=~ s/dc=([^,]*)//gi; # remove DC=* parts
	$machine	=~ s/([^,]*)=//gi; # leave only values from the rest
	my $m		= join ('/', reverse (split (/,/,$machine)));	
	$cmd		= $cmd. " createcomputer=\"$m\"" if $m;
    }

    my $result = SCR->Execute(".target.bash_output", $cmd);
    $cmd =~ s/(-U '[^%]*)%[^']*'/$1'/; # hide password in debug
    y2internal("$cmd => ".Dumper($result));
    
    # check the exit code, return nil on success
    if ($result && defined $result->{exit} && $result->{exit} == 0) {
	$TestJoinCache{$domain} = 1;
	return undef;
    }

    # otherwise return stderr
    $TestJoinCache{$domain} = undef;
    my $error = $result->{stdout} ne "" ? $result->{stdout} : $result->{stderr};
    return ($result && $error ne "") ? $error : "unknown error";
}

# Joins the host into a given domain. If user is provided, it will use
# the user and password for joining. If the user is nil, joining will
# be done anonymously.
#
# Attention: It will write the configuration for domain before settings the password
#
# @param domain	a name of a domain to be left
# @param user		username to be used for joining, or nil for anonymous
# @param passwd		password for the user
# @return string	an error message or nil if successful
BEGIN{$TYPEINFO{Leave}= [ "function","string","string","string","string"]}
sub Leave {

    my ($self, $domain, $user, $passwd) = @_;
    
    my $tmpdir		= SCR->Read (".target.tmpdir");
    my $realm		= SambaAD->Realm ();
    
    my $cmd = "net ads leave -U '"
	. String->Quote ($user) . "%" . String->Quote ($passwd) . "'";

    my $result = SCR->Execute(".target.bash_output", $cmd);
    $cmd =~ s/(-U '[^%]*)%[^']*'/$1'/; # hide password in the log
    y2internal("$cmd => ".Dumper($result));
    
    # check the exit code, return nil on success
    if ($result && defined $result->{exit} && $result->{exit} == 0) {
	# force new testjoin run (maybe domain from first testjoin was replaced
	# by realm => empty whole hash)
	%TestJoinCache	= ();
	return undef;
    }

    # otherwise return stderr
    my $error = $result->{stdout} ne "" ? $result->{stdout} : $result->{stderr};
    return ($result && $error ne "") ? $error : "unknown error";
}


8;

ACC SHELL 2018