Skip to content
marten edited this page Jan 27, 2017 · 42 revisions

Welcome to the radcli wiki!

Goal: Radcli supports authenticating with username/password. Figure out how to support authentication using a keytab and principal name.

Use a keytab and a principal name when authenticating

Create and use a keytab file

>ktutil
addent -password -p [email protected] -k 1 -e RC4-HMAC
- enter password for username -
wkt realm_ad.keytab
q
> kdestroy
> kinit [email protected] -k -t realm_ad.keytab; 
> klist
Ticket cache: KEYRING:persistent:1000:1000
Default principal: [email protected]

Valid starting       Expires              Service principal
2017-01-27 10:30:00  2017-01-27 20:30:00  krbtgt/[email protected]
	renew until 2017-02-03 10:30:00

Preset a computer using the principal name and the credentials cache (-C option).

> adcli preset-computer server_temp -D example.com -U Administrator -C
> ltrace -o preset_trace.ltrace  adcli preset-computer server_temp -D example.com -U Administrator -C
computer-name: server_temp

> grep "krb5_cc" preset_trace.ltrace 
krb5_cc_default(0x7fcf58bfe490, 0x7fcf58bf0110, 1, 0)                                                           = 0
krb5_cc_get_full_name(0x7fcf58bfe490, 0x7fcf58bfe8d0, 0x7fcf58bf0058, 0x7fcf58bfe8e0)                           = 0
gss_krb5_ccache_name(0x7ffcabb30ee8, 0x7fcf58c030f0, 0, 0)                                                      = 0
gss_krb5_ccache_name(0x7ffcabb30ee8, 0, 0, 0)                                                                   = 0
krb5_cc_close(0x7fcf58bfe490, 0x7fcf58bfe8d0, 0x7fcf5745d770, 0x7fcf58c03110)                                   = 0
[marten@radcli radcli]$ 

Adcli function calls

C symbol: user_password

  File     Function                     Line
0 adconn.c <global>                       52 char *user_password;
1 adconn.c ensure_user_password          270 conn->user_password != NULL)
2 adconn.c ensure_user_password          274 conn->user_password = (conn->password_func) (ADCLI_LOGIN_USER_ACCOUNT,
3 adconn.c ensure_user_password          279 if (conn->user_password == NULL) {
4 adconn.c _adcli_kinit_user_creds       566 conn->user_password, null_prompter, NULL,
5 adconn.c adcli_conn_get_user_password 1364 return conn->user_password;
6 adconn.c adcli_conn_set_user_password 1372 _adcli_str_set (&conn->user_password, value);

adcli_conn_connect (adcli_conn *conn)
{
        adcli_result res = ADCLI_SUCCESS;

        return_unexpected_if_fail (conn != NULL);

        res = adcli_conn_discover (conn);
        if (res != ADCLI_SUCCESS)
                return res;

        /* - Connect to LDAP server */
        res = connect_to_directory (conn);
        if (res != ADCLI_SUCCESS)
                return res;

        /* Guarantee consistency and communication with one dc */
        res = setup_krb5_conf_snippet (conn);
        if (res != ADCLI_SUCCESS)
                return res;

        return_unexpected_if_fail (conn->k5 == NULL);
        res = _adcli_krb5_init_context (&conn->k5);
        if (res != ADCLI_SUCCESS)
                return res;

        /* Login with admin credentials now, setup login ccache */
        res = prep_kerberos_and_kinit (conn); <-----------------------------------------------
        if (res != ADCLI_SUCCESS)
                return res;

        /* - And finally authenticate */
        res = authenticate_to_directory (conn);
        if (res != ADCLI_SUCCESS)
                return res;

        lookup_short_name (conn);
        return ADCLI_SUCCESS;
}

Test

require 'radcli'

adconn = Adcli::AdConn.new("example.com")
adconn.set_login_user("Administrator")
adconn.set_domain_realm("EXAMPLE.COM")
adconn.set_domain_controller("dc.example.com")
res = adconn.connect
[marten@radcli radcli]$ irb
irb(main):001:0> require 'radcli'
=> true
irb(main):002:0> 
irb(main):003:0* adconn = Adcli::AdConn.new("example.com")
=> #<Adcli::AdConn:0x0000000131b4f0>
irb(main):004:0> adconn.set_login_user("Administrator")
=> #<Adcli::AdConn:0x0000000131b4f0>
irb(main):005:0> adconn.set_domain_realm("EXAMPLE.COM")
=> #<Adcli::AdConn:0x0000000131b4f0>
irb(main):006:0> adconn.set_domain_controller("dc.example.com")
=> #<Adcli::AdConn:0x0000000131b4f0>
irb(main):007:0> res = adconn.connect
No admin password or credential cache specified=> #<Adcli::AdConn:0x0000000131b4f0>
irb(main):008:0> 
static adcli_result
ensure_user_password (adcli_conn *conn)
{
        if (conn->login_ccache_name != NULL ||
            conn->user_password != NULL)
                return ADCLI_SUCCESS;

        if (conn->password_func) {
                conn->user_password = (conn->password_func) (ADCLI_LOGIN_USER_ACCOUNT,
                                                             conn->user_name, 0,
                                                             conn->password_data);
        }

        if (conn->user_password == NULL) {
                _adcli_err ("No admin password or credential cache specified");
                return ADCLI_ERR_CREDENTIALS;
        }

        return ADCLI_SUCCESS;
}
static adcli_result
kinit_with_user_credentials (adcli_conn *conn,
                             krb5_ccache ccache)
{
        adcli_result res;
        krb5_error_code code;
        char *name;

        /* Build out the admin principal name */
        if (!conn->user_name) {
                if (asprintf (&conn->user_name, "Administrator@%s", conn->domain_realm) < 0)
                        return_unexpected_if_reached ();
        } else if (strchr (conn->user_name, '@') == NULL) {
                if (asprintf (&name, "%s@%s", conn->user_name, conn->domain_realm) < 0)
                        return_unexpected_if_reached ();
                free (conn->user_name);
                conn->user_name = name;
        }

        res = ensure_user_password (conn);
        if (res != ADCLI_SUCCESS)
                return res;

        code = _adcli_kinit_user_creds (conn, NULL, ccache, NULL);

        if (code == 0) {
                conn->login_type = ADCLI_LOGIN_USER_ACCOUNT;
                _adcli_info ("Authenticated as user: %s", conn->user_name);
                return ADCLI_SUCCESS;
        }

        return handle_kinit_krb5_code (conn, ADCLI_LOGIN_USER_ACCOUNT, conn->user_name, code);
}
Functions calling this function: kinit_with_user_credentials

  File     Function                Line
0 adconn.c prep_kerberos_and_kinit 718 res = kinit_with_user_credentials (conn, ccache);

Clone this wiki locally