From 428cf878944eca7b0762e1e434cc4895dff98372 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Wed, 10 Apr 2013 13:46:27 +0200 Subject: [PATCH] Add support for setting operatingSystem and related attrs * Add new arguments to join command: --os-name --os-version and --os-service-pack * These are not supported when a computer is claiming an account on its own credentials. https://bugs.freedesktop.org/show_bug.cgi?id=54489 --- doc/adcli.xml | 32 ++++++++++++++++++++ library/Makefile.am | 1 + library/adenroll.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++- library/adenroll.h | 15 ++++++++++ library/adldap.c | 4 +-- tools/computer.c | 35 ++++++++++++++++++++++ 6 files changed, 168 insertions(+), 3 deletions(-) diff --git a/doc/adcli.xml b/doc/adcli.xml index 923378c..4f26574 100644 --- a/doc/adcli.xml +++ b/doc/adcli.xml @@ -236,6 +236,22 @@ Password for Administrator: 'computer' and 'user' authentication. + + Set the operating system name on the computer + account. The default depends on where adcli was built, but + is usually something like 'linux-gnu'. + + + + Set the operating system service pack on the computer + account. Not set by default. + + + + Set the operating system version on the computer + account. Not set by default. + + Additional service name for a kerberos principal to be created on the computer account. This @@ -442,6 +458,22 @@ Password for Administrator: automatic joins. + + Set the operating system name on the computer + account. The default depends on where adcli was built, but + is usually something like 'linux-gnu'. + + + + Set the operating system service pack on the computer + account. Not set by default. + + + + Set the operating system version on the computer + account. Not set by default. + + Additional service name for a kerberos principal to be created on the computer account. This diff --git a/library/Makefile.am b/library/Makefile.am index 749689d..39e8fd1 100644 --- a/library/Makefile.am +++ b/library/Makefile.am @@ -3,6 +3,7 @@ include $(top_srcdir)/Makefile.decl INCLUDES = \ -I$(top_srcdir) \ -DADCLI_UNSTABLE_API \ + -DHOST_TRIPLET=\"$(host_triplet)\" \ $(NULL) MODULE_SRCS = \ diff --git a/library/adenroll.c b/library/adenroll.c index 27ae91a..21d07bb 100644 --- a/library/adenroll.c +++ b/library/adenroll.c @@ -67,6 +67,10 @@ struct _adcli_enroll { char **service_principals; int service_principals_explicit; + char *os_name; + char *os_version; + char *os_service_pack; + krb5_kvno kvno; char *keytab_name; int keytab_name_is_krb5; @@ -563,7 +567,10 @@ filter_for_necessary_updates (adcli_enroll *enroll, */ if (login == ADCLI_LOGIN_COMPUTER_ACCOUNT) { - if (strcasecmp (mods[in]->mod_type, "userAccountControl") == 0) + if (strcasecmp (mods[in]->mod_type, "userAccountControl") == 0 || + strcasecmp (mods[in]->mod_type, "operatingSystem") == 0 || + strcasecmp (mods[in]->mod_type, "operatingSystemVersion") == 0 || + strcasecmp (mods[in]->mod_type, "operatingSystemServicePack") == 0) continue; } @@ -621,11 +628,20 @@ create_or_update_computer_account (adcli_enroll *enroll, LDAPMod sAMAccountName = { 0, "sAMAccountName", { vals_sAMAccountName, } }; char *vals_userAccountControl[] = { "69632", NULL }; /* WORKSTATION_TRUST_ACCOUNT | DONT_EXPIRE_PASSWD */ LDAPMod userAccountControl = { 0, "userAccountControl", { vals_userAccountControl, } }; + char *vals_operatingSystem[] = { enroll->os_name, NULL }; + LDAPMod operatingSystem = { 0, "operatingSystem", { vals_operatingSystem, } }; + char *vals_operatingSystemVersion[] = { enroll->os_version, NULL }; + LDAPMod operatingSystemVersion = { 0, "operatingSystemVersion", { vals_operatingSystemVersion, } }; + char *vals_operatingSystemServicePack[] = { enroll->os_service_pack, NULL }; + LDAPMod operatingSystemServicePack = { 0, "operatingSystemServicePack", { vals_operatingSystemServicePack, } }; LDAPMod *mods[] = { &objectClass, &sAMAccountName, &userAccountControl, + &operatingSystem, + &operatingSystemVersion, + &operatingSystemServicePack, NULL, }; @@ -1624,6 +1640,7 @@ adcli_enroll * adcli_enroll_new (adcli_conn *conn) { adcli_enroll *enroll; + const char *value; return_val_if_fail (conn != NULL, NULL); @@ -1632,6 +1649,16 @@ adcli_enroll_new (adcli_conn *conn) enroll->conn = adcli_conn_ref (conn); enroll->refs = 1; + + /* Use the latter sections of host triple as OS name */ + value = strchr (HOST_TRIPLET, '-'); + if (value == NULL) + value = HOST_TRIPLET; + else + value++; + enroll->os_name = strdup (value); + return_val_if_fail (enroll->os_name != NULL, NULL); + return enroll; } @@ -1656,6 +1683,10 @@ enroll_free (adcli_enroll *enroll) free (enroll->computer_dn); free (enroll->keytab_enctypes); + free (enroll->os_name); + free (enroll->os_version); + free (enroll->os_service_pack); + _adcli_strv_free (enroll->service_names); _adcli_strv_free (enroll->service_principals); _adcli_password_free (enroll->computer_password); @@ -1928,3 +1959,54 @@ adcli_enroll_set_keytab_enctypes (adcli_enroll *enroll, enroll->keytab_enctypes = newval; enroll->keytab_enctypes_explicit = (newval != NULL); } + +const char * +adcli_enroll_get_os_name (adcli_enroll *enroll) +{ + return_val_if_fail (enroll != NULL, NULL); + return enroll->os_name; +} + +void +adcli_enroll_set_os_name (adcli_enroll *enroll, + const char *value) +{ + return_if_fail (enroll != NULL); + if (value && value[0] == '\0') + value = NULL; + _adcli_str_set (&enroll->os_name, value); +} + +const char * +adcli_enroll_get_os_version (adcli_enroll *enroll) +{ + return_val_if_fail (enroll != NULL, NULL); + return enroll->os_version; +} + +void +adcli_enroll_set_os_version (adcli_enroll *enroll, + const char *value) +{ + return_if_fail (enroll != NULL); + if (value && value[0] == '\0') + value = NULL; + _adcli_str_set (&enroll->os_version, value); +} + +const char * +adcli_enroll_get_os_service_pack (adcli_enroll *enroll) +{ + return_val_if_fail (enroll != NULL, NULL); + return enroll->os_service_pack; +} + +void +adcli_enroll_set_os_service_pack (adcli_enroll *enroll, + const char *value) +{ + return_if_fail (enroll != NULL); + if (value && value[0] == '\0') + value = NULL; + _adcli_str_set (&enroll->os_service_pack, value); +} diff --git a/library/adenroll.h b/library/adenroll.h index 6e7ae65..9dfb5f8 100644 --- a/library/adenroll.h +++ b/library/adenroll.h @@ -108,4 +108,19 @@ krb5_enctype * adcli_enroll_get_keytab_enctypes (adcli_enroll *enroll); void adcli_enroll_set_keytab_enctypes (adcli_enroll *enroll, krb5_enctype *enctypes); +const char * adcli_enroll_get_os_name (adcli_enroll *enroll); + +void adcli_enroll_set_os_name (adcli_enroll *enroll, + const char *value); + +const char * adcli_enroll_get_os_version (adcli_enroll *enroll); + +void adcli_enroll_set_os_version (adcli_enroll *enroll, + const char *value); + +const char * adcli_enroll_get_os_service_pack (adcli_enroll *enroll); + +void adcli_enroll_set_os_service_pack (adcli_enroll *enroll, + const char *value); + #endif /* ADENROLL_H_ */ diff --git a/library/adldap.c b/library/adldap.c index 89ba09f..ae8a1cf 100644 --- a/library/adldap.c +++ b/library/adldap.c @@ -219,12 +219,12 @@ _adcli_ldap_filter_for_add (void *unused, return -1; if (mod->mod_op & LDAP_MOD_BVALUES) { - if (mod->mod_vals.modv_bvals == NULL && + if (mod->mod_vals.modv_bvals == NULL || mod->mod_vals.modv_bvals[0] == NULL) return -1; mod->mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES; } else { - if (mod->mod_vals.modv_strvals == NULL && + if (mod->mod_vals.modv_strvals == NULL || mod->mod_vals.modv_strvals[0] == NULL) return -1; mod->mod_op = LDAP_MOD_ADD; diff --git a/tools/computer.c b/tools/computer.c index 692b8bb..fd77629 100644 --- a/tools/computer.c +++ b/tools/computer.c @@ -34,6 +34,8 @@ static void dump_details (adcli_conn *conn, adcli_enroll *enroll) { + const char *value; + printf ("[domain]\n"); printf ("domain-name = %s\n", adcli_conn_get_domain_name (conn)); printf ("domain-realm = %s\n", adcli_conn_get_domain_realm (conn)); @@ -47,6 +49,18 @@ dump_details (adcli_conn *conn, printf ("computer-name = %s\n", adcli_conn_get_computer_name (conn)); printf ("computer-dn = %s\n", adcli_enroll_get_computer_dn (enroll)); + value = adcli_enroll_get_os_name (enroll); + if (value) + printf ("os-name = %s\n", value); + + value = adcli_enroll_get_os_version (enroll); + if (value) + printf ("os-version = %s\n", value); + + value = adcli_enroll_get_os_service_pack (enroll); + if (value) + printf ("os-service-pack = %s\n", value); + printf ("[keytab]\n"); printf ("kvno = %d\n", adcli_enroll_get_kvno (enroll)); printf ("keytab = %s\n", adcli_enroll_get_keytab_name (enroll)); @@ -73,6 +87,9 @@ typedef enum { opt_stdin_password, opt_one_time_password, opt_show_details, + opt_os_name, + opt_os_version, + opt_os_service_pack, } Option; static adcli_tool_desc common_usages[] = { @@ -94,6 +111,9 @@ static adcli_tool_desc common_usages[] = { "which the computer account should be placed." }, { opt_service_name, "additional service name for a kerberos\n" "service principal to be created on the account" }, + { opt_os_name, "the computer operating system name", }, + { opt_os_version, "the computer operating system version", }, + { opt_os_service_pack, "the computer operating system service pack", }, { opt_no_password, "don't prompt for or read a password" }, { opt_prompt_password, "prompt for a password if necessary" }, { opt_stdin_password, "read a password from stdin (until EOF) if\n" @@ -196,6 +216,15 @@ parse_option (Option opt, case opt_one_time_password: adcli_enroll_set_computer_password (enroll, optarg); return; + case opt_os_name: + adcli_enroll_set_os_name (enroll, optarg); + return; + case opt_os_version: + adcli_enroll_set_os_version (enroll, optarg); + return; + case opt_os_service_pack: + adcli_enroll_set_os_service_pack (enroll, optarg); + return; case opt_verbose: return; @@ -250,6 +279,9 @@ adcli_tool_computer_join (adcli_conn *conn, { "domain-ou", required_argument, NULL, opt_domain_ou }, { "computer-ou", required_argument, NULL, opt_domain_ou }, /* compat */ { "service-name", required_argument, NULL, opt_service_name }, + { "os-name", optional_argument, NULL, opt_os_name }, + { "os-version", optional_argument, NULL, opt_os_version }, + { "os-service-pack", optional_argument, NULL, opt_os_service_pack }, { "show-details", no_argument, NULL, opt_show_details }, { "verbose", no_argument, NULL, opt_verbose }, { "help", no_argument, NULL, 'h' }, @@ -336,6 +368,9 @@ adcli_tool_computer_preset (adcli_conn *conn, { "prompt-password", no_argument, 0, opt_prompt_password }, { "one-time-password", required_argument, 0, opt_one_time_password }, { "service-name", required_argument, NULL, opt_service_name }, + { "os-name", optional_argument, NULL, opt_os_name }, + { "os-version", optional_argument, NULL, opt_os_version }, + { "os-service-pack", optional_argument, NULL, opt_os_service_pack }, { "verbose", no_argument, NULL, opt_verbose }, { "help", no_argument, NULL, 'h' }, { 0 }, -- 1.8.1.4