Use default NTLM domain cc config
The NTLM GSS mechanism now supports default credential handles (and acquiring handles for default credentials with desired_name == GSS_C_NO_NAME).
This commit is contained in:
@@ -33,18 +33,18 @@
|
|||||||
|
|
||||||
#include "ntlm.h"
|
#include "ntlm.h"
|
||||||
|
|
||||||
OM_uint32 GSSAPI_CALLCONV _gss_ntlm_acquire_cred
|
OM_uint32 GSSAPI_CALLCONV
|
||||||
(OM_uint32 * min_stat,
|
_gss_ntlm_acquire_cred(OM_uint32 *min_stat,
|
||||||
gss_const_name_t desired_name,
|
gss_const_name_t desired_name,
|
||||||
OM_uint32 time_req,
|
OM_uint32 time_req,
|
||||||
const gss_OID_set desired_mechs,
|
const gss_OID_set desired_mechs,
|
||||||
gss_cred_usage_t cred_usage,
|
gss_cred_usage_t cred_usage,
|
||||||
gss_cred_id_t * output_cred_handle,
|
gss_cred_id_t *output_cred_handle,
|
||||||
gss_OID_set * actual_mechs,
|
gss_OID_set *actual_mechs,
|
||||||
OM_uint32 * time_rec
|
OM_uint32 *time_rec)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
ntlm_name name = (ntlm_name) desired_name;
|
ntlm_name name = (ntlm_name) desired_name;
|
||||||
|
const char *domain = NULL;
|
||||||
OM_uint32 maj_stat;
|
OM_uint32 maj_stat;
|
||||||
ntlm_ctx ctx;
|
ntlm_ctx ctx;
|
||||||
|
|
||||||
@@ -55,17 +55,14 @@ OM_uint32 GSSAPI_CALLCONV _gss_ntlm_acquire_cred
|
|||||||
if (time_rec)
|
if (time_rec)
|
||||||
*time_rec = GSS_C_INDEFINITE;
|
*time_rec = GSS_C_INDEFINITE;
|
||||||
|
|
||||||
if (desired_name == NULL)
|
|
||||||
return GSS_S_NO_CRED;
|
|
||||||
|
|
||||||
if (cred_usage == GSS_C_BOTH || cred_usage == GSS_C_ACCEPT) {
|
if (cred_usage == GSS_C_BOTH || cred_usage == GSS_C_ACCEPT) {
|
||||||
|
|
||||||
maj_stat = _gss_ntlm_allocate_ctx(min_stat, &ctx);
|
maj_stat = _gss_ntlm_allocate_ctx(min_stat, &ctx);
|
||||||
if (maj_stat != GSS_S_COMPLETE)
|
if (maj_stat != GSS_S_COMPLETE)
|
||||||
return maj_stat;
|
return maj_stat;
|
||||||
|
|
||||||
maj_stat = (*ctx->server->nsi_probe)(min_stat, ctx->ictx,
|
domain = name != NULL ? name->domain : NULL;
|
||||||
name->domain);
|
maj_stat = (*ctx->server->nsi_probe)(min_stat, ctx->ictx, domain);
|
||||||
{
|
{
|
||||||
gss_ctx_id_t context = (gss_ctx_id_t)ctx;
|
gss_ctx_id_t context = (gss_ctx_id_t)ctx;
|
||||||
OM_uint32 junk;
|
OM_uint32 junk;
|
||||||
@@ -79,7 +76,7 @@ OM_uint32 GSSAPI_CALLCONV _gss_ntlm_acquire_cred
|
|||||||
|
|
||||||
*min_stat = _gss_ntlm_get_user_cred(name, &cred);
|
*min_stat = _gss_ntlm_get_user_cred(name, &cred);
|
||||||
if (*min_stat)
|
if (*min_stat)
|
||||||
return GSS_S_FAILURE;
|
return GSS_S_NO_CRED;
|
||||||
cred->usage = cred_usage;
|
cred->usage = cred_usage;
|
||||||
|
|
||||||
*output_cred_handle = (gss_cred_id_t)cred;
|
*output_cred_handle = (gss_cred_id_t)cred;
|
||||||
|
@@ -35,11 +35,13 @@
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
from_file(const char *fn, const char *target_domain,
|
from_file(const char *fn, const char *target_domain,
|
||||||
char **username, struct ntlm_buf *key)
|
char **domainp, char **usernamep, struct ntlm_buf *key)
|
||||||
{
|
{
|
||||||
char *str, buf[1024];
|
char *str, buf[1024];
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
|
*domainp = NULL;
|
||||||
|
|
||||||
f = fopen(fn, "r");
|
f = fopen(fn, "r");
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
@@ -52,14 +54,20 @@ from_file(const char *fn, const char *target_domain,
|
|||||||
continue;
|
continue;
|
||||||
str = NULL;
|
str = NULL;
|
||||||
d = strtok_r(buf, ":", &str);
|
d = strtok_r(buf, ":", &str);
|
||||||
if (d && strcasecmp(target_domain, d) != 0)
|
free(*domainp);
|
||||||
|
if (d && target_domain != NULL && strcasecmp(target_domain, d) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
*domainp = strdup(d);
|
||||||
|
if (*domainp == NULL)
|
||||||
|
return ENOMEM;
|
||||||
u = strtok_r(NULL, ":", &str);
|
u = strtok_r(NULL, ":", &str);
|
||||||
p = strtok_r(NULL, ":", &str);
|
p = strtok_r(NULL, ":", &str);
|
||||||
if (u == NULL || p == NULL)
|
if (u == NULL || p == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*username = strdup(u);
|
*usernamep = strdup(u);
|
||||||
|
if (*usernamep == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
heim_ntlm_nt_key(p, key);
|
heim_ntlm_nt_key(p, key);
|
||||||
|
|
||||||
@@ -74,17 +82,22 @@ from_file(const char *fn, const char *target_domain,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
get_user_file(const ntlm_name target_name,
|
get_user_file(const ntlm_name target_name,
|
||||||
char **username, struct ntlm_buf *key)
|
char **domainp, char **usernamep, struct ntlm_buf *key)
|
||||||
{
|
{
|
||||||
|
const char *domain;
|
||||||
const char *fn;
|
const char *fn;
|
||||||
|
|
||||||
|
*domainp = NULL;
|
||||||
|
|
||||||
if (issuid())
|
if (issuid())
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
|
|
||||||
|
domain = target_name != NULL ? target_name->domain : NULL;
|
||||||
|
|
||||||
fn = getenv("NTLM_USER_FILE");
|
fn = getenv("NTLM_USER_FILE");
|
||||||
if (fn == NULL)
|
if (fn == NULL)
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
if (from_file(fn, target_name->domain, username, key) == 0)
|
if (from_file(fn, domain, domainp, usernamep, key) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
@@ -95,7 +108,7 @@ get_user_file(const ntlm_name target_name,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
get_user_ccache(const ntlm_name name, char **username, struct ntlm_buf *key)
|
get_user_ccache(const ntlm_name name, char **domainp, char **usernamep, struct ntlm_buf *key)
|
||||||
{
|
{
|
||||||
krb5_context context = NULL;
|
krb5_context context = NULL;
|
||||||
krb5_principal client;
|
krb5_principal client;
|
||||||
@@ -105,7 +118,8 @@ get_user_ccache(const ntlm_name name, char **username, struct ntlm_buf *key)
|
|||||||
krb5_data data;
|
krb5_data data;
|
||||||
int aret;
|
int aret;
|
||||||
|
|
||||||
*username = NULL;
|
*domainp = NULL;
|
||||||
|
*usernamep = NULL;
|
||||||
krb5_data_zero(&data);
|
krb5_data_zero(&data);
|
||||||
key->length = 0;
|
key->length = 0;
|
||||||
key->data = NULL;
|
key->data = NULL;
|
||||||
@@ -124,22 +138,40 @@ get_user_ccache(const ntlm_name name, char **username, struct ntlm_buf *key)
|
|||||||
|
|
||||||
ret = krb5_unparse_name_flags(context, client,
|
ret = krb5_unparse_name_flags(context, client,
|
||||||
KRB5_PRINCIPAL_UNPARSE_NO_REALM,
|
KRB5_PRINCIPAL_UNPARSE_NO_REALM,
|
||||||
username);
|
usernamep);
|
||||||
krb5_free_principal(context, client);
|
krb5_free_principal(context, client);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
aret = asprintf(&confname, "ntlm-key-%s", name->domain);
|
if (name != NULL) {
|
||||||
if (aret == -1) {
|
*domainp = strdup(name->domain);
|
||||||
krb5_clear_error_message(context);
|
} else {
|
||||||
ret = ENOMEM;
|
krb5_data data_domain;
|
||||||
|
|
||||||
|
krb5_data_zero(&data_domain);
|
||||||
|
ret = krb5_cc_get_config(context, id, NULL, "default-ntlm-domain",
|
||||||
|
&data_domain);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
*domainp = strndup(data_domain.data, data_domain.length);
|
||||||
|
krb5_data_free(&data_domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*domainp == NULL) {
|
||||||
|
ret = krb5_enomem(context);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = krb5_cc_get_config(context, id, NULL,
|
aret = asprintf(&confname, "ntlm-key-%s", *domainp);
|
||||||
confname, &data);
|
if (aret == -1) {
|
||||||
if (ret)
|
ret = krb5_enomem(context);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = krb5_cc_get_config(context, id, NULL, confname, &data);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
key->data = malloc(data.length);
|
key->data = malloc(data.length);
|
||||||
if (key->data == NULL) {
|
if (key->data == NULL) {
|
||||||
@@ -170,15 +202,16 @@ _gss_ntlm_get_user_cred(const ntlm_name target_name,
|
|||||||
if (cred == NULL)
|
if (cred == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
ret = get_user_file(target_name, &cred->username, &cred->key);
|
ret = get_user_file(target_name,
|
||||||
|
&cred->domain, &cred->username, &cred->key);
|
||||||
if (ret)
|
if (ret)
|
||||||
ret = get_user_ccache(target_name, &cred->username, &cred->key);
|
ret = get_user_ccache(target_name,
|
||||||
|
&cred->domain, &cred->username, &cred->key);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
free(cred);
|
free(cred);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
cred->domain = strdup(target_name->domain);
|
|
||||||
*rcred = cred;
|
*rcred = cred;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
Reference in New Issue
Block a user