Create computer account via ssh/udm

join

#1

After a successful installation, our Linux clients start a shell script that still performs various configurations. One of these steps is joining our Univention domain. Similar like this:
https://docs.software-univention.de/domain-4.3.html#ext-dom-ubuntu

With one exception this works perfect:

When I start the following example script on the UCS master directly, the client will be entered correct.

#!/bin/bash

ldap_base="dc=nothing,dc=intranet"
clientname="wla666"
password="Welcome!2Heaven!"
client_mac="90:1b:0e:ff:ff:ff"
client_ip="192.168.66.6"
domainname="nothing.intranet"

udm computers/linux create \  
    --position "cn=computers,$ldap_base" \
    --set name="$clientname" --set password="$password" \
    --set operatingSystem="Debian" \    
    --set operatingSystemVersion="666" \
    --set network="cn=default,cn=networks,$ldap_base" \
    --set mac="$client_mac" \ 
    --set ip="$client_ip" \
    --set dnsEntryZoneForward="zoneName=$domainname,cn=dns,$ldap_base $client_ip" \
    --set dnsEntryZoneReverse="zoneName=66.168.192.in-addr.arpa,cn=dns,$ldap_base $client_ip" \
    --set dhcpEntryZone="cn=$domainname,cn=dhcp,$ldap_base $client_ip $client_mac"

When I start it remote via ssh…

#!/bin/bash

ldap_base="dc=nothing,dc=intranet"
clientname="wla666"
password="Welcome!2Heaven!"
client_mac="90:1b:0e:ff:ff:ff"
client_ip="192.168.66.6"
domainname="nothing.intranet"

ssh -n root@server udm computers/linux create \
    --position "cn=computers,$ldap_base" \
    --set name="$clientname" --set password="$password" \
    --set operatingSystem="Debian" \
    --set operatingSystemVersion="666" \
    --set network="cn=default,cn=networks,$ldap_base" \
    --set mac="$client_mac" \ 
    --set ip="$client_ip" \
    --set dnsEntryZoneForward="zoneName=$domainname,cn=dns,$ldap_base $client_ip" \
    --set dnsEntryZoneReverse="zoneName=66.168.192.in-addr.arpa,cn=dns,$ldap_base $client_ip" \
    --set dhcpEntryZone="cn=$domainname,cn=dhcp,$ldap_base $client_ip $client_mac"

… I get as response:

WARNING: the following arguments are ignored: "192.168.66.6" "--set" "dnsEntryZoneReverse=zoneName=66.168.192.in-addr.arpa,cn=dns,dc=nothing,dc=intranet" "192.168.66.6" "--set" "dhcpEntryZone=cn=nothing.intranet,cn=dhcp,dc=nothing,dc=intranet" "192.168.66.6" "90:1b:0e:ff:ff:ff"
Object created: cn=wla666,cn=computers,dc=nothing,dc=intranet

Indeed, when I check the computer information on the web interface, the DNS and DHCP information for this client is empty. I have to correct this manually each time.
I am a little bit obscured about the difference. What goes wrong here…
I am glad for any advice.

Best,
reneum


#2

Hey,

the spaces in the following entries are the culprits:

The problem is that your local bash escapes them properly and hands the entry over to ssh, but ssh doesn’t do any quoting of its own when passing that to the shell on the other side. What’s executed by ssh on the other side is actually this:

udm computers/linux create \
    --position cn=computers,dc=nothing,dc=intranet \
    --set name=wla66 --set password=Welcome!2Heaven! \
    --set operatingSystem=Debian \
    --set operatingSystemVersion=666 \
    --set network=cn=default,cn=networks,dc=nothing,dc=intranet \
    --set mac=90:1b:0e:ff:ff:ff \
    --set ip=192.168.66.6 \
    --set dnsEntryZoneForward=zoneName=nothing.intranet,cn=dns,dc=nothing,dc=intranet 192.168.66.6 \
    --set dnsEntryZoneReverse=zoneName=66.168.192.in-addr.arpa,cn=dns,dc=nothing,dc=intranet 192.168.66.6 \
    --set dhcpEntryZone=cn=nothing.intranet,cn=dhcp,dc=nothing,dc=intranet 192.168.66.6 90:1b:0e:ff:ff:ff

which is equivalent to:

udm computers/linux create \
    --position cn=computers,dc=nothing,dc=intranet \
    --set name=wla66 \
    --set password=Welcome!2Heaven! \
    --set operatingSystem=Debian \
    --set operatingSystemVersion=666 \
    --set network=cn=default,cn=networks,dc=nothing,dc=intranet \
    --set mac=90:1b:0e:ff:ff:ff \
    --set ip=192.168.66.6 \
    --set dnsEntryZoneForward=zoneName=nothing.intranet,cn=dns,dc=nothing,dc=intranet \
    192.168.66.6 \
    --set dnsEntryZoneReverse=zoneName=66.168.192.in-addr.arpa,cn=dns,dc=nothing,dc=intranet \
    192.168.66.6 \
    --set dhcpEntryZone=cn=nothing.intranet,cn=dhcp,dc=nothing,dc=intranet \
    192.168.66.6 \
    90:1b:0e:ff:ff:ff

You’ll have to add escaping that is effective on the other side, too. It might look like this:

…
    --set dnsEntryZoneForward="zoneName=$domainname,cn=dns,$ldap_base\\ $client_ip" \
    --set dnsEntryZoneReverse="zoneName=66.168.192.in-addr.arpa,cn=dns,$ldap_base\\ $client_ip" \
    --set dhcpEntryZone="cn=$domainname,cn=dhcp,$ldap_base\\ $client_ip\\ $client_mac"

Note the double backslashes that I’ve inserted in the two lines. The goal is to pass a backslash to the shell on the other side. However, the local shell also interprets backslashes, therefore we have to escape the backslash for the other side with an additional backslash that’s stripped by the local shell — hence double backslashes.

If you want to debug such things, I recommend using a helper script (maybe called dumper.sh) on the other side that dumps one argument per line:

#!/bin/bash

let idx=1

for p in "$@" ; do
  echo "${idx} ${p}"
  let idx=idx+1
done

Then execute your command like this:

ssh -n root@ucstest-master /root/dumper.sh udm computers/linux create …

Kind regards,
mosu


#3

Perfect, this helps a lot! :+1:
Thank you very much for your time and the detailed explanation!