#!/bin/sh

if [ ! $(whoami) = "root" ]; then
 echo "You need to be root to run this command."
 exit 1
fi

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin; export PATH

RUNNING_FREEBSD_VERSION=$(uname -r | awk -F '-' '{print $1}')
RUNNING_FREEBSD_ARCH=$(uname -m)

case ${RUNNING_FREEBSD_VERSION} in
  "9.2"|"9.3"|"10.0"|"10.1"|"10.2") ;;
  *)
    echo "Unsupported FreeBSD version \"${RUNNING_FREEBSD_VERSION}\"."
    echo "Supported versions are \"9.2\", \"9.3\", \"10.0\", \"10.1\" or \"10.2\". Exiting."
    exit 1
  ;;
esac

run_command() {

  #############################################################################
  ## This function exists for two reasons; 1) to give better feedback to the ##
  ## user and 2) provide a rudimentary form of error checking to just bail   ##
  ## out if things go south.                                                 ##
  ##                                                                         ##
  ## Two important things to know about it.                                  ##
  ## - Always remember to begin and end the command you want to have run     ##
  ## with quotation marks to have it passed through as just one long string. ##
  ## - Any quotation marks inside the command have to be commented out by    ##
  ## prefixing with a backslash so that they pass through "echo" as literal  ##
  ## quotes. Example:                                                        ##
  ## run_command "echo \"\""                                                 ##
  ## To pass through those same characters but literally(\"):                ##
  ## run_command "echo \\\"\\\""                                             ##
  #############################################################################

  RUN_DIR="/var/tmp"
  if [ ! -d ${RUN_DIR} ]; then
    mkdir ${RUN_DIR}
    chown root:$(id root | awk '{gsub(/\(/, " "); gsub(/\)/, " "); if ($3 ~ "gid") print $4}') ${RUN_DIR}
    chmod 777 ${RUN_DIR}
  fi
  COMMAND=$(mktemp ${RUN_DIR}/run_command.cmd.XXXXXX)
  OUTPUT=$(mktemp ${RUN_DIR}/run_command.out.XXXXXX)
  echo "#!/bin/sh" > ${COMMAND}
  echo "$1" >> ${COMMAND}
  chmod +x ${COMMAND}
  echo "+-- Running command:"
  echo "$(cat ${COMMAND} | egrep -v "^#!/bin/sh$")"
  ${COMMAND} > ${OUTPUT} 2>&1
  if [ $? -gt "0" ]; then
    echo "+-- Command Failed!"
    echo "+-- Output was:"
    cat ${OUTPUT}
    echo ""
    rm ${OUTPUT} > /dev/null 2>&1
    rm ${COMMAND} > /dev/null 2>&1
    exit 1
  else
    echo "+-- Output was:"
    cat ${OUTPUT}
    echo "+-- Command succeeded."
    echo ""
  fi
  rm ${OUTPUT} > /dev/null 2>&1
  rm ${COMMAND} > /dev/null 2>&1
}

while [ $(ping -c 1 172.16.1.9 2>/dev/null | grep "bytes from" | awk 'END{print NR}') = "0" ]; do
 echo "+-- No response from primary DNS, sleeping."
 sleep 1
done

IFACE=$(for i in $(ifconfig | awk '/^[a-zA-Z]+[0-9]+/ {gsub(/\:/, ""); print $1}'); do if ifconfig $i | grep -q $(netstat -rn | awk '/default/ {gsub(/\./, " "); print $2"."$3"."$4}'); then echo $i; fi; done)
IPADDR=$(ifconfig ${IFACE} | awk '($1 == "inet") {sub(/\:/, ""); print $2}')
NETMASK=$(netstat -rn | grep $(echo ${IPADDR} | awk -F '.' '{print $1"."$2"."$3".0"}') | awk '{sub(/\//, " "); print $2}')
FULL_COMPUTERNAME=$(host $(echo ${IPADDR}) | awk '{print $5}' | awk -F '.' '{print $1}')
DOMAIN_NAME=$(host $(echo ${IPADDR}) | awk '{print $5}' | awk '{sub(/\.$/,"");printf("%s\n",substr($1,index($1,".")+1))}')
HOST_NAME=${FULL_COMPUTERNAME}.${DOMAIN_NAME}
if [ $(echo ${FULL_COMPUTERNAME} | awk -F "-" '{print $1"-"$2"-"$3"-"$4}') = "ovirt-0-1a-4a" ]; then
  SHORT_COMPUTERNAME=$(echo ${FULL_COMPUTERNAME} | awk -F "-" '{print $1"-"$5"-"$6"-"$7}')
  NETBIOS_COMPUTERNAME=$(echo ${SHORT_COMPUTERNAME} | awk '{print toupper ($1)}')
else
  NETBIOS_COMPUTERNAME=$(echo ${FULL_COMPUTERNAME} | awk '{print toupper ($1)}')
fi
for DISK in $(ls -1 /dev/ | egrep '(da|vtbd)' | egrep -v [a-z]+[0-9]+[a-z][0-9]+); do
  HDD=$(camcontrol devlist | egrep "\(${DISK},|,${DISK}\)" | egrep '(ATA|QEMU HARDDISK)' | awk 'END{print NR}')
  if [ ${HDD} = 1 ]; then
    HDDS="${HDDS} /dev/${DISK}"
  else
    DEVICE_NUMBER=$(echo ${DISK} | awk '{gsub(/[a-zA-Z]/, ""); print}')
    if [ $(grep "vtblk${DEVICE_NUMBER}" /var/run/dmesg.boot | awk 'END{print NR}') -gt "0" ]; then
      HDDS="${HDDS} /dev/${DISK}"
    fi
  fi
done
HDDS=$(echo ${HDDS} | sed 's/^ //')

if ! grep -q 'WITH_PKGNG="YES"' /etc/make.conf 2>/dev/null; then
  run_command "echo 'WITH_PKGNG=\"YES\"' >>/etc/make.conf"
fi

if [ -f /var/db/pkg/pkgdb.db ]; then
  run_command "pkg2ng"
fi

if [ -f /etc/pkg/FreeBSD.conf ]; then
  if grep -q 'enabled: yes' /etc/pkg/FreeBSD.conf 2>/dev/null; then
    run_command "sed -i '' 's/enabled: yes/enabled: no/' /etc/pkg/FreeBSD.conf"
  fi
fi

if [ ! -d /usr/local/etc/ssl/certs ]; then
  run_command "mkdir -p /usr/local/etc/ssl/certs"
fi

if [ ! -f /usr/local/etc/ssl/certs/pkg.cert ]; then
  run_command "cat > /usr/local/etc/ssl/certs/pkg.cert << EOF
-----BEGIN PUBLIC KEY-----
[payload removed: 736 characters in 12 lines]
-----END PUBLIC KEY-----
EOF"
fi

if [ ! -f /usr/local/etc/pkg.conf ]; then
  run_command "cat > /usr/local/etc/pkg.conf << EOF
REPO_AUTOUPDATE     : YES
ALIAS               : {
  all-depends: query %dn-%dv,
  annotations: info -A,
  build-depends: info -qd,
  download: fetch,
  iinfo: info -i -g -x,
  isearch: search -i -g -x,
  leaf: query -e \"%a == 0\" \"%n-%v\",
  leaf: query -e \"%a == 0\" \"%n-%v\",
  list: info -ql,
  origin: info -qo,
  provided-depends: info -qb,
  raw: info -R,
  required-depends: info -qr,
  shared-depends: info -qB,
  show: info -f -k,
  size: info -sq,
  }
EOF"
fi

REPOS_DIR="/usr/local/etc/pkg/repos"

if [ ! -d ${REPOS_DIR} ]; then
  run_command "mkdir -p ${REPOS_DIR}"
fi

if [ ! -f ${REPOS_DIR}/builder.conf ]; then
  run_command "echo 'builder: {' > ${REPOS_DIR}/builder.conf"
  case "${RUNNING_FREEBSD_VERSION}" in
    "9.2")
      run_command "echo '    url             : \"http://builder.inparadise.se/repo/release92amd64-default\",' >> ${REPOS_DIR}/builder.conf"
    ;;
    "9.3")
      run_command "echo '    url             : \"http://builder.inparadise.se/repo/release93amd64-default\",' >> ${REPOS_DIR}/builder.conf"
    ;;
    "10.0")
      case "${RUNNING_FREEBSD_ARCH}" in
        "amd64")
          run_command "echo '    url             : \"http://builder.inparadise.se/repo/release10amd64-default\",' >> ${REPOS_DIR}/builder.conf"
        ;;
        "i386")
          run_command "echo '    url             : \"http://builder.inparadise.se/repo/release10i386-default\",' >> ${REPOS_DIR}/builder.conf"
        ;;
      esac
    ;;
    "10.1")
      run_command "echo '    url             : \"http://builder.inparadise.se/repo/release101amd64-default\",' >> ${REPOS_DIR}/builder.conf"
    ;;
    "10.2")
      run_command "echo '    url             : \"http://builder.inparadise.se/repo/release102amd64-default\",' >> ${REPOS_DIR}/builder.conf"
    ;;
  esac
  run_command "cat >> ${REPOS_DIR}/builder.conf << EOF
    signature_type  : \"PUBKEY\",
    pubkey          : \"/usr/local/etc/ssl/certs/pkg.cert\",
    enabled         : yes,
    mirror_type     : NONE,
}
EOF"
fi

if [ -f ${REPOS_DIR}/FreeBSD.conf ]; then
  if grep -q 'enabled: yes' ${REPOS_DIR}/FreeBSD.conf 2>/dev/null; then
    run_command "sed -i '' 's/enabled: yes/enabled: no/' ${REPOS_DIR}/FreeBSD.conf"
  fi
else
  run_command "echo 'FreeBSD: { enabled: no }' > ${REPOS_DIR}/FreeBSD.conf"
fi

run_command "pkg update -f"
run_command "pkg upgrade -fy pkg"

run_command "pkg install -y bash samba43 pam_mkhomedir sudo openssl puppet38 ssmtp"
run_command "sed -i '' \"/# root:       me@my.domain/{G;s/$/root:       karli.sjoberg@gmail.com/;}\" /etc/aliases"
run_command "newaliases"
run_command "cat > /usr/local/etc/ssmtp/ssmtp.conf << EOF
root=karli.sjoberg@gmail.com
mailhub=smtp.gmail.com:587
rewriteDomain=inparadise.se
hostname=${HOST_NAME}
UseTLS=Yes
UseSTARTTLS=Yes
AuthUser=karli.sjoberg@gmail.com
AuthPass=Storm08Kira12Tintin14_
FromLineOverride=yes
EOF"
run_command "sed -i '' -e 's,^[^#],#&,g' /etc/mail/mailer.conf"
run_command "cat >> /etc/mail/mailer.conf << EOF
sendmail        /usr/local/sbin/ssmtp
send-mail       /usr/local/sbin/ssmtp
mailq           /usr/local/sbin/ssmtp
newaliases      /usr/local/sbin/ssmtp
hoststat        /usr/bin/true
purgestat       /usr/bin/true
EOF"
run_command "sed -i '' \"s/Charlie &:\/root:\/bin\/csh/${FULL_COMPUTERNAME}@inparadise.se:\/root:\/bin\/csh/\" /etc/master.passwd"
run_command "pwd_mkdb -p /etc/master.passwd"
run_command "cat > /etc/krb5.conf << EOF
 [logging]
    default = FILE:/var/log/krb5.log

[libdefaults]
    default_realm = INPARADISE.SE
    kdc_timesync = 1
    ccache_type = 4
    forwardable = true
    proxiable = true

[realms]
    INPARADISE.SE = {
        kdc = inparadise.se
        admin_server = inparadise.se
        default_domain = INPARADISE.SE
    }

[domain_realm]
    .inparadise.se = INPARADISE.SE
    inparadise.se = INPARADISE.SE
EOF"
run_command "cat > /usr/local/etc/smb4.conf << EOF
 [global]

	max protocol = SMB3

        socket options = TCP_NODELAY SO_SNDBUF=131072 SO_RCVBUF=131072
        use sendfile = yes
        min receivefile size = 16384
        aio read size = 16384
        aio write size = 16384
        aio write behind = yes

        idmap config *:backend = tdb
        idmap config *:range = 70001-80000
        idmap config INPARADISE:backend = ad
        idmap config INPARADISE:schema_mode = rfc2307
        idmap config INPARADISE:range = 500-40000

        winbind nss info = rfc2307
        winbind offline logon = true
        winbind use default domain = yes
        winbind enum users  = yes
        winbind enum groups = yes

        server string = %h server (Samba, FreeBSD)
        security = ads
        realm = INPARADISE.SE
        workgroup = INPARADISE
        template homedir = /usr/home/%U
        template shell = /usr/local/bin/bash
        username map = /usr/local/etc/samba/usermap
        log level = 3
        log file = /var/log/samba4/samba.log
        max log size = 50

        netbios name = ${NETBIOS_COMPUTERNAME}
        interfaces = ${IPADDR}/${NETMASK}
	nmbd bind explicit broadcast = no

[homes]
	comment = Home Directories
	browseable = yes
	read only = no
EOF"
if [ ! -d /usr/local/etc/samba ]; then
  mkdir /usr/local/etc/samba
fi
run_command "cat > /usr/local/etc/samba/usermap << EOF
root=Administrator
guest=nobody
EOF"
run_command "cp /etc/nsswitch.conf /etc/nsswitch.conf.orig"
run_command "sed -i '' -e 's/group: compat/group: files winbind/' -e 's/passwd: compat/passwd: files winbind/' /etc/nsswitch.conf"
run_command "cp /etc/nsswitch.conf /etc/nsswitch.conf.ad"
run_command "cp /etc/pam.d/system /etc/pam.d/system.orig"
run_command "cat > /etc/pam.d/system << EOF
# auth
auth            sufficient      pam_opie.so                     no_warn no_fake_prompts
auth            requisite       pam_opieaccess.so               no_warn allow_local
auth            sufficient      pam_krb5.so                     no_warn try_first_pass
#auth           sufficient      pam_ssh.so                      no_warn try_first_pass
auth            sufficient      pam_unix.so                     no_warn try_first_pass nullok
auth            required        /usr/local/lib/pam_winbind.so   try_first_pass

# account
account         required        pam_krb5.so
account         required        pam_login_access.so
account         required        pam_unix.so

# session
#session        optional        pam_ssh.so
session         required        /usr/local/lib/pam_mkhomedir.so
session         required        pam_lastlog.so          no_fail

# password
password        sufficient      pam_krb5.so             no_warn try_first_pass
password        required        pam_unix.so             no_warn try_first_pass
EOF"
run_command "cp /etc/pam.d/system /etc/pam.d/system.ad"
run_command "cp /etc/pam.d/sshd /etc/pam.d/sshd.orig"
run_command "cat > /etc/pam.d/sshd << EOF
# auth
auth            sufficient      pam_opie.so                     no_warn no_fake_prompts
auth            requisite       pam_opieaccess.so               no_warn allow_local
auth            sufficient      pam_krb5.so                     no_warn try_first_pass
#auth           sufficient      pam_ssh.so                      no_warn try_first_pass
auth            sufficient      pam_unix.so                     no_warn try_first_pass nullok
auth            required        /usr/local/lib/pam_winbind.so   try_first_pass

# account
account         required        pam_nologin.so
account         required        pam_krb5.so
account         required        pam_login_access.so
account         required        pam_unix.so

# session
#session        optional        pam_ssh.so
session         required        /usr/local/lib/pam_mkhomedir.so
session         required        pam_permit.so           no_fail

# password
password        sufficient      pam_krb5.so             no_warn try_first_pass
password        required        pam_unix.so             no_warn try_first_pass
EOF"
run_command "cp /etc/pam.d/sshd /etc/pam.d/sshd.ad"
run_command "sed -i '' -e \"/root ALL=(ALL) ALL/{G;s/$/admin ALL=(ALL) ! ALL/;}\" -e \"/admin ALL=(ALL) ! ALL/{G;s/$/%domain\\\\ admins ALL=(ALL) ALL/;}\" /usr/local/etc/sudoers"
run_command "cat >> /etc/rc.conf << EOF
samba_server_enable=\"YES\"
smbd_enable=\"YES\"
nmbd_enable=\"YES\"
winbindd_enable=\"YES\"
EOF"
run_command "cat > /usr/local/etc/puppet/puppet.conf << EOF
[main]
    # The Puppet log directory.
    # The default value is '\\\$vardir/log'.
    logdir = /var/log/puppet

    # Where Puppet PID files are kept.
    # The default value is '\\\$vardir/run'.
    rundir = /var/run/puppet

    # Where SSL certificates are kept.
    # The default value is '\\\$confdir/ssl'.
    ssldir = \\\$vardir/ssl

[agent]
    # The file in which puppetd stores a list of the classes
    # associated with the retrieved configuratiion.  Can be loaded in
    # the separate ``puppet`` executable using the ``--loadclasses``
    # option.
    # The default value is '\\\$confdir/classes.txt'.
    classfile = \\\$vardir/classes.txt

    # Where puppetd caches the local configuration.  An
    # extension indicating the cache format is added automatically.
    # The default value is '\\\$confdir/localconfig'.
    localconfig = \\\$vardir/localconfig

    runinterval = 300
    report = true
EOF"
run_command "cat > /usr/local/etc/puppet/auth.conf << EOF
path /run
auth any
method save
allow puppet.inparadise.se

# this one is not stricly necessary, but it has the merit
# to show the default policy which is deny everything else
path /
auth any
EOF"
run_command "cat >> /etc/rc.conf << EOF
#puppet_enable=\"YES\"
#puppet_flags=\"--server puppet.inparadise.se\"
EOF"
echo -n "Type in Domain Administrator account name: "
read DOMADMIN
net ads join -U ${DOMADMIN}
run_command "service samba_server start"
