summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2013-08-21 22:05:45 -0400
committerSimo Sorce <simo@redhat.com>2013-08-21 22:05:45 -0400
commit38e2c7b67d358942eb5e2ced247f581945175fc9 (patch)
tree8e9c09059dcd2c1064d81801319594d7bf13cdf1
parent5f7d6d53d45b91ee196159428b5c149a290d8bed (diff)
downloadgss-ntlmssp-38e2c7b67d358942eb5e2ced247f581945175fc9.tar.gz
gss-ntlmssp-38e2c7b67d358942eb5e2ced247f581945175fc9.tar.xz
gss-ntlmssp-38e2c7b67d358942eb5e2ced247f581945175fc9.zip
Add implementation of gss_inquire_context
Also add source and target names to the context.
-rw-r--r--src/gss_names.c9
-rw-r--r--src/gss_ntlmssp.h14
-rw-r--r--src/gss_sec_ctx.c110
-rw-r--r--src/gss_spi.c21
4 files changed, 154 insertions, 0 deletions
diff --git a/src/gss_names.c b/src/gss_names.c
index fe95aeb..7ccc3a0 100644
--- a/src/gss_names.c
+++ b/src/gss_names.c
@@ -244,6 +244,7 @@ int gssntlm_copy_name(struct gssntlm_name *src, struct gssntlm_name *dst)
int ret;
dst->type = src->type;
switch (src->type) {
+ case GSSNTLM_NAME_NULL:
case GSSNTLM_NAME_ANON:
break;
case GSSNTLM_NAME_USER:
@@ -302,6 +303,11 @@ uint32_t gssntlm_duplicate_name(uint32_t *minor_status,
in = (struct gssntlm_name *)input_name;
+ if (in->type == GSSNTLM_NAME_NULL) {
+ *dest_name = GSS_C_NO_NAME;
+ return GSS_S_COMPLETE;
+ }
+
out = calloc(1, sizeof(struct gssntlm_name));
if (!out) {
*minor_status = ENOMEM;
@@ -322,6 +328,8 @@ void gssntlm_int_release_name(struct gssntlm_name *name)
if (!name) return;
switch (name->type) {
+ case GSSNTLM_NAME_NULL:
+ return;
case GSSNTLM_NAME_ANON:
break;
case GSSNTLM_NAME_USER:
@@ -332,6 +340,7 @@ void gssntlm_int_release_name(struct gssntlm_name *name)
safefree(name->data.server.name);
break;
}
+ name->type = GSSNTLM_NAME_NULL;
}
uint32_t gssntlm_release_name(uint32_t *minor_status,
diff --git a/src/gss_ntlmssp.h b/src/gss_ntlmssp.h
index 308ecfd..de56bad 100644
--- a/src/gss_ntlmssp.h
+++ b/src/gss_ntlmssp.h
@@ -62,6 +62,7 @@
struct gssntlm_name {
enum ntlm_name_type {
+ GSSNTLM_NAME_NULL,
GSSNTLM_NAME_ANON,
GSSNTLM_NAME_USER,
GSSNTLM_NAME_SERVER
@@ -132,6 +133,9 @@ struct gssntlm_ctx {
struct ntlm_buffer chal_msg;
struct ntlm_buffer auth_msg;
+ struct gssntlm_name source_name;
+ struct gssntlm_name target_name;
+
uint8_t server_chal[8];
/* requested gss fags */
@@ -269,4 +273,14 @@ uint32_t gssntlm_unwrap(uint32_t *minor_status,
gss_buffer_t output_message_buffer,
int *conf_state,
gss_qop_t *qop_state);
+
+uint32_t gssntlm_inquire_context(uint32_t *minor_status,
+ gss_ctx_id_t context_handle,
+ gss_name_t *src_name,
+ gss_name_t *targ_name,
+ uint32_t *lifetime_rec,
+ gss_OID *mech_type,
+ uint32_t *ctx_flags,
+ int *locally_initiated,
+ int *open);
#endif /* _GSS_NTLMSSP_H_ */
diff --git a/src/gss_sec_ctx.c b/src/gss_sec_ctx.c
index fb574f4..7736244 100644
--- a/src/gss_sec_ctx.c
+++ b/src/gss_sec_ctx.c
@@ -114,6 +114,12 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status,
}
} else {
cred = (struct gssntlm_cred *)claimant_cred_handle;
+ if ((cred->type != GSSNTLM_CRED_ANON)
+ && (cred->type != GSSNTLM_CRED_USER)) {
+ retmin = EINVAL;
+ retmaj = GSS_S_BAD_NAMETYPE;
+ goto done;
+ }
}
retmin = gssntlm_copy_creds(cred, &ctx->cred);
@@ -122,6 +128,21 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status,
goto done;
}
+ retmin = gssntlm_copy_name(&ctx->cred.cred.user.user,
+ &ctx->source_name);
+ if (retmin) {
+ retmaj = GSS_S_FAILURE;
+ goto done;
+ }
+
+ if (server) {
+ retmin = gssntlm_copy_name(server, &ctx->target_name);
+ if (retmin) {
+ retmaj = GSS_S_FAILURE;
+ goto done;
+ }
+ }
+
ctx->gss_flags = req_flags;
ctx->role = GSSNTLM_CLIENT;
@@ -572,6 +593,9 @@ uint32_t gssntlm_delete_sec_context(uint32_t *minor_status,
ctx->chal_msg.length = 0;
ctx->auth_msg.length = 0;
+ gssntlm_int_release_name(&ctx->source_name);
+ gssntlm_int_release_name(&ctx->target_name);
+
safefree(*context_handle);
if (ret) {
@@ -800,6 +824,12 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status,
if (retmaj) goto done;
}
+ retmin = gssntlm_copy_name(server_name, &ctx->target_name);
+ if (retmin) {
+ retmaj = GSS_S_FAILURE;
+ goto done;
+ }
+
computer_name = strdup(server_name->data.server.name);
if (!computer_name) {
retmin = ENOMEM;
@@ -941,6 +971,12 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status,
NULL, NULL);
if (retmaj) goto done;
+ retmin = gssntlm_copy_name(gss_usrname, &ctx->source_name);
+ if (retmin) {
+ retmaj = GSS_S_FAILURE;
+ goto done;
+ }
+
/* NTLMv2 Key */
retmin = NTOWFv2(ctx->ntlm, &usr_cred->cred.user.nt_hash,
usr_cred->cred.user.user.data.user.name,
@@ -1042,3 +1078,77 @@ done:
ntlm_free_buffer_data(&target_info);
return retmaj;
}
+
+uint32_t gssntlm_inquire_context(uint32_t *minor_status,
+ gss_ctx_id_t context_handle,
+ gss_name_t *src_name,
+ gss_name_t *targ_name,
+ uint32_t *lifetime_rec,
+ gss_OID *mech_type,
+ uint32_t *ctx_flags,
+ int *locally_initiated,
+ int *open)
+{
+ struct gssntlm_ctx *ctx;
+ uint32_t retmaj;
+ uint32_t retmin;
+ time_t now;
+
+ *minor_status = 0;
+
+ ctx = (struct gssntlm_ctx *)context_handle;
+ if (!ctx) return GSS_S_NO_CONTEXT;
+
+ if (src_name) {
+ retmaj = gssntlm_duplicate_name(&retmin,
+ (gss_name_t)&ctx->source_name,
+ src_name);
+ if (retmaj) return retmaj;
+ }
+
+ if (targ_name) {
+ retmaj = gssntlm_duplicate_name(&retmin,
+ (gss_name_t)&ctx->target_name,
+ targ_name);
+ if (retmaj) return retmaj;
+ }
+
+ if (mech_type) {
+ *mech_type = discard_const(&gssntlm_oid);
+ }
+
+ if (ctx_flags) {
+ *ctx_flags = ctx->gss_flags;
+ }
+
+ if (locally_initiated) {
+ if (ctx->role == GSSNTLM_CLIENT) {
+ *locally_initiated = 1;
+ } else {
+ *locally_initiated = 0;
+ }
+ }
+
+ if (ctx->established) {
+ if (lifetime_rec) {
+ now = time(NULL);
+ if (ctx->expiration_time > now) {
+ *lifetime_rec = 0;
+ } else {
+ *lifetime_rec = ctx->expiration_time - now;
+ }
+ }
+ if (open) {
+ *open = 1;
+ }
+ } else {
+ if (lifetime_rec) {
+ *lifetime_rec = 0;
+ }
+ if (open) {
+ *open = 0;
+ }
+ }
+
+ return GSS_S_COMPLETE;
+}
diff --git a/src/gss_spi.c b/src/gss_spi.c
index 8139d3c..d456f14 100644
--- a/src/gss_spi.c
+++ b/src/gss_spi.c
@@ -232,3 +232,24 @@ OM_uint32 gss_unwrap(OM_uint32 *minor_status,
conf_state,
qop_state);
}
+
+OM_uint32 gss_inquire_context(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ gss_name_t *src_name,
+ gss_name_t *targ_name,
+ OM_uint32 *lifetime_rec,
+ gss_OID *mech_type,
+ OM_uint32 *ctx_flags,
+ int *locally_initiated,
+ int *open)
+{
+ return gssntlm_inquire_context(minor_status,
+ context_handle,
+ src_name,
+ targ_name,
+ lifetime_rec,
+ mech_type,
+ ctx_flags,
+ locally_initiated,
+ open);
+}