-
Notifications
You must be signed in to change notification settings - Fork 6
Home
marten edited this page Jan 27, 2017
·
42 revisions
Welcome to the radcli wiki!
Goal: Radcli supports authenticating with username/password. Study adcli and figure out how to authenticate using a keytab and a principalname.
>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
> 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 <-- prep_kerberos_and_kinit
krb5_cc_get_full_name(0x7fcf58bfe490, 0x7fcf58bfe8d0, 0x7fcf58bf0058, 0x7fcf58bfe8e0) = 0 <-- prep_kerberos_and_kinit
gss_krb5_ccache_name(0x7ffcabb30ee8, 0x7fcf58c030f0, 0, 0) = 0 <-- authenticate_to_directory
gss_krb5_ccache_name(0x7ffcabb30ee8, 0, 0, 0) = 0
krb5_cc_close(0x7fcf58bfe490, 0x7fcf58bfe8d0, 0x7fcf5745d770, 0x7fcf58c03110) = 0
[marten@radcli radcli]$
... prep_kerberos_and_kinit -> authenticate_to_directory -> ...
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;
}
...
if (strcmp (conn->login_ccache_name, "") == 0) {
code = krb5_cc_default (conn->k5, &conn->ccache);
if (code == 0) {
free (conn->login_ccache_name);
conn->login_ccache_name = NULL;
code = krb5_cc_get_full_name (conn->k5, conn->ccache,
&conn->login_ccache_name);
conn->login_ccache_name_is_krb5 = 1;
return_unexpected_if_fail (code == 0);
}
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>
C symbol: login_ccache_name
File Function Line
0 adconn.c <global> 55 char *login_ccache_name;
1 adconn.c ensure_user_password 269 if (conn->login_ccache_name != NULL ||
2 adconn.c prep_kerberos_and_kinit 645 if (conn->login_ccache_name != NULL) {
3 adconn.c prep_kerberos_and_kinit 657 if (strcmp (conn->login_ccache_name, "") == 0) {
4 adconn.c prep_kerberos_and_kinit 660 free (conn->login_ccache_name);
5 adconn.c prep_kerberos_and_kinit 661 conn->login_ccache_name = NULL;
6 adconn.c prep_kerberos_and_kinit 663 &conn->login_ccache_name);
7 adconn.c prep_kerberos_and_kinit 668 code = krb5_cc_resolve (conn->k5, conn->login_ccache_name, &conn->ccache);
8 adconn.c prep_kerberos_and_kinit 673 conn->login_ccache_name, krb5_get_error_message (NULL, code));
9 adconn.c prep_kerberos_and_kinit 724 &conn->login_ccache_name);
a adconn.c authenticate_to_directory 1001 assert (conn->login_ccache_name != NULL);
b adconn.c authenticate_to_directory 1004 status = gss_krb5_ccache_name (&minor, conn->login_ccache_name, NULL);
c adconn.c adcli_conn_get_login_ccache_name 1423 return conn->login_ccache_name;
d adconn.c adcli_conn_set_login_ccache_name 1439 if (conn->login_ccache_name) {
e adconn.c adcli_conn_set_login_ccache_name 1441 krb5_free_string (conn->k5, conn->login_ccache_name);
f adconn.c adcli_conn_set_login_ccache_name 1443 free (conn->login_ccache_name);
g adconn.c adcli_conn_set_login_ccache_name 1451 conn->login_ccache_name = newval;
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);
Set login_ccache_name to "" using adcli_conn_set_login_ccache_name. Implement set_login_ccache_name in radcli.
kdestroy
# Kinit using rkerberos
require "rkerberos"
principal = "Administrator"
keytab="/tmp/realm_ad.keytab"
krb5 = Kerberos::Krb5.new
ccache = Kerberos::Krb5::CredentialsCache.new
krb5.get_init_creds_keytab principal, keytab, nil, ccache
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")
adconn.set_login_ccache_name("")
res = adconn.connect
enroll = Adcli::AdEnroll.new(adconn)
enroll.set_computer_name("test")
enroll.set_computer_password("password")
enroll.join()
enroll = Adcli::AdEnroll.new(adconn)
enroll.set_computer_name("test")
enroll.set_computer_password("newpass")
enroll.password()
enroll = Adcli::AdEnroll.new(adconn)
enroll.set_computer_name("test")
enroll.delete()