diff options
-rw-r--r-- | src/gss_auth.c | 95 | ||||
-rw-r--r-- | src/gss_creds.c | 99 | ||||
-rw-r--r-- | src/gss_err.c | 15 | ||||
-rw-r--r-- | src/gss_names.c | 174 | ||||
-rw-r--r-- | src/gss_ntlmssp.h | 15 | ||||
-rw-r--r-- | src/gss_sec_ctx.c | 297 | ||||
-rw-r--r-- | src/gss_serialize.c | 332 | ||||
-rw-r--r-- | src/gss_signseal.c | 71 |
8 files changed, 575 insertions, 523 deletions
diff --git a/src/gss_auth.c b/src/gss_auth.c index 91a231d..fd1139c 100644 --- a/src/gss_auth.c +++ b/src/gss_auth.c @@ -5,7 +5,7 @@ #include "gss_ntlmssp.h" -uint32_t gssntlm_cli_auth(uint32_t *minor, +uint32_t gssntlm_cli_auth(uint32_t *minor_status, struct gssntlm_ctx *ctx, struct gssntlm_cred *cred, struct ntlm_buffer *target_info, @@ -23,8 +23,8 @@ uint32_t gssntlm_cli_auth(uint32_t *minor, struct ntlm_buffer mic = { micbuf, 16 }; bool add_mic = false; bool key_exch; - uint32_t retmaj = GSS_S_FAILURE; - uint32_t retmin = 0; + uint32_t retmaj; + uint32_t retmin; switch (cred->type) { @@ -35,8 +35,7 @@ uint32_t gssntlm_cli_auth(uint32_t *minor, memset(&nt_chal_resp, 0, sizeof(nt_chal_resp)); lm_chal_resp.data = malloc(1); if (!lm_chal_resp.data) { - retmin = ENOMEM; - retmaj = GSS_S_FAILURE; + set_GSSERR(ENOMEM); goto done; } lm_chal_resp.data[0] = 0; @@ -54,7 +53,7 @@ uint32_t gssntlm_cli_auth(uint32_t *minor, if (target_info->length == 0 && input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS) { - retmaj = GSS_S_UNAVAILABLE; + set_GSSERRS(0, GSS_S_BAD_BINDINGS); goto done; } @@ -68,8 +67,7 @@ uint32_t gssntlm_cli_auth(uint32_t *minor, input_chan_bindings->acceptor_addrtype != 0 || input_chan_bindings->acceptor_address.length != 0 || input_chan_bindings->application_data.length == 0) { - retmin = EINVAL; - retmaj = GSS_S_BAD_BINDINGS; + set_GSSERRS(EINVAL, GSS_S_BAD_BINDINGS); goto done; } cb.length = input_chan_bindings->application_data.length; @@ -91,9 +89,9 @@ uint32_t gssntlm_cli_auth(uint32_t *minor, &srv_time, add_mic_ptr); if (retmin) { if (retmin == ERR_DECODE) { - retmaj = GSS_S_DEFECTIVE_TOKEN; + set_GSSERRS(0, GSS_S_DEFECTIVE_TOKEN); } else { - retmaj = GSS_S_FAILURE; + set_GSSERR(0); } goto done; } @@ -102,8 +100,7 @@ uint32_t gssntlm_cli_auth(uint32_t *minor, long int tdiff; tdiff = ntlm_timestamp_now() - srv_time; if ((tdiff / 10000000) > MAX_CHALRESP_LIFETIME) { - retmin = EINVAL; - retmaj = GSS_S_CONTEXT_EXPIRED; + set_GSSERRS(EINVAL, GSS_S_CONTEXT_EXPIRED); goto done; } } @@ -112,7 +109,7 @@ uint32_t gssntlm_cli_auth(uint32_t *minor, /* Random client challenge */ retmin = RAND_BUFFER(&cli_chal); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } @@ -122,7 +119,7 @@ uint32_t gssntlm_cli_auth(uint32_t *minor, cred->cred.user.user.data.user.domain, &ntlmv2_key); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } @@ -132,7 +129,7 @@ uint32_t gssntlm_cli_auth(uint32_t *minor, srv_time, &client_target_info, &nt_chal_resp); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } @@ -144,7 +141,7 @@ uint32_t gssntlm_cli_auth(uint32_t *minor, client_chal, &lm_chal_resp); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } } @@ -158,7 +155,7 @@ uint32_t gssntlm_cli_auth(uint32_t *minor, retmin = ntlmv2_session_base_key(&ntlmv2_key, &nt_proof, &key_exchange_key); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } } else { @@ -174,15 +171,14 @@ uint32_t gssntlm_cli_auth(uint32_t *minor, lm_chal_resp.length = 24; lm_chal_resp.data = calloc(1, lm_chal_resp.length); if (!nt_chal_resp.data || !lm_chal_resp.data) { - retmin = ENOMEM; - retmaj = GSS_S_FAILURE; + set_GSSERR(ENOMEM); goto done; } /* Random client challenge */ retmin = RAND_BUFFER(&cli_chal); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } @@ -192,7 +188,7 @@ uint32_t gssntlm_cli_auth(uint32_t *minor, ext_sec, ctx->server_chal, client_chal, &nt_chal_resp); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } @@ -203,7 +199,7 @@ uint32_t gssntlm_cli_auth(uint32_t *minor, ext_sec, ctx->server_chal, client_chal, &lm_chal_resp); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } } @@ -211,7 +207,7 @@ uint32_t gssntlm_cli_auth(uint32_t *minor, retmin = ntlm_session_base_key(&cred->cred.user.nt_hash, &session_base_key); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } @@ -222,7 +218,7 @@ uint32_t gssntlm_cli_auth(uint32_t *minor, &session_base_key, &lm_chal_resp, &key_exchange_key); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } } @@ -232,7 +228,7 @@ uint32_t gssntlm_cli_auth(uint32_t *minor, retmin = ntlm_exported_session_key(&key_exchange_key, key_exch, &ctx->exported_session_key); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } @@ -241,7 +237,7 @@ uint32_t gssntlm_cli_auth(uint32_t *minor, &ctx->exported_session_key, &encrypted_random_session_key); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } } @@ -260,7 +256,7 @@ uint32_t gssntlm_cli_auth(uint32_t *minor, add_mic ? &auth_mic : NULL, &ctx->auth_msg); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } @@ -272,7 +268,7 @@ uint32_t gssntlm_cli_auth(uint32_t *minor, retmin = ntlm_mic(&ctx->exported_session_key, &ctx->nego_msg, &ctx->chal_msg, &ctx->auth_msg, &mic); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } /* now that we have the mic, copy it into the auth message */ @@ -282,30 +278,28 @@ uint32_t gssntlm_cli_auth(uint32_t *minor, ctx->int_flags |= NTLMSSP_CTX_FLAG_AUTH_WITH_MIC; } - retmin = 0; - retmaj = GSS_S_COMPLETE; + set_GSSERRS(0, GSS_S_COMPLETE); break; case GSSNTLM_CRED_EXTERNAL: retmin = external_cli_auth(ctx, cred, in_flags, input_chan_bindings); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } - retmaj = GSS_S_COMPLETE; + set_GSSERRS(0, GSS_S_COMPLETE); break; default: - retmin = EINVAL; - retmaj = GSS_S_FAILURE; + set_GSSERR(EINVAL); } done: ntlm_free_buffer_data(&client_target_info); ntlm_free_buffer_data(&nt_chal_resp); ntlm_free_buffer_data(&lm_chal_resp); - *minor = retmin; - return retmaj; + + return GSSERR(); } @@ -315,7 +309,7 @@ bool is_ntlm_v1(struct ntlm_buffer *nt_chal_resp) } -uint32_t gssntlm_srv_auth(uint32_t *minor, +uint32_t gssntlm_srv_auth(uint32_t *minor_status, struct gssntlm_ctx *ctx, struct gssntlm_cred *cred, struct ntlm_buffer *nt_chal_resp, @@ -332,15 +326,13 @@ uint32_t gssntlm_srv_auth(uint32_t *minor, int retries; if (key_exchange_key->length != 16) { - *minor = EINVAL; - return GSS_S_FAILURE; + return GSSERRS(EINVAL, GSS_S_FAILURE); } ntlm_v1 = is_ntlm_v1(nt_chal_resp); if (ntlm_v1 && !gssntlm_sec_lm_ok(ctx) && !gssntlm_sec_ntlm_ok(ctx)) { - *minor = EPERM; - return GSS_S_FAILURE; + return GSSERRS(EPERM, GSS_S_FAILURE); } ext_sec = (ctx->neg_flags & NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY); @@ -379,7 +371,7 @@ uint32_t gssntlm_srv_auth(uint32_t *minor, cred->cred.user.user.data.user.name, domstr, &ntlmv2_key); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } @@ -397,7 +389,7 @@ uint32_t gssntlm_srv_auth(uint32_t *minor, } if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } @@ -405,7 +397,7 @@ uint32_t gssntlm_srv_auth(uint32_t *minor, retmin = ntlm_session_base_key(&cred->cred.user.nt_hash, &session_base_key); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } break; @@ -420,7 +412,7 @@ uint32_t gssntlm_srv_auth(uint32_t *minor, retmin = ntlmv2_session_base_key(&ntlmv2_key, &nt_proof, &session_base_key); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } break; @@ -429,14 +421,13 @@ uint32_t gssntlm_srv_auth(uint32_t *minor, retmin = external_srv_auth(ctx, cred, nt_chal_resp, lm_chal_resp, &session_base_key); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } break; default: - retmin = EINVAL; - retmaj = GSS_S_FAILURE; + set_GSSERR(EINVAL); goto done; } @@ -448,7 +439,7 @@ uint32_t gssntlm_srv_auth(uint32_t *minor, &session_base_key, lm_chal_resp, key_exchange_key); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } } else { @@ -456,10 +447,8 @@ uint32_t gssntlm_srv_auth(uint32_t *minor, session_base_key.data, session_base_key.length); } - retmaj = GSS_S_COMPLETE; - retmin = 0; + set_GSSERRS(0, GSS_S_COMPLETE); done: - *minor = retmin; - return retmaj; + return GSSERR(); } diff --git a/src/gss_creds.c b/src/gss_creds.c index 080de5d..530de7b 100644 --- a/src/gss_creds.c +++ b/src/gss_creds.c @@ -328,15 +328,14 @@ uint32_t gssntlm_acquire_cred_from(uint32_t *minor_status, { struct gssntlm_cred *cred; struct gssntlm_name *name; - uint32_t retmaj = GSS_S_COMPLETE; - uint32_t retmin = 0; + uint32_t retmaj; + uint32_t retmin; name = (struct gssntlm_name *)desired_name; cred = calloc(1, sizeof(struct gssntlm_cred)); if (!cred) { - retmin = errno; - return GSS_S_FAILURE; + return GSSERRS(errno, GSS_S_FAILURE); } /* FIXME: should we split the cred union and allow GSS_C_BOTH ? @@ -355,8 +354,7 @@ uint32_t gssntlm_acquire_cred_from(uint32_t *minor_status, cred_usage = GSS_C_INITIATE; break; default: - retmin = EINVAL; - retmaj = GSS_S_CRED_UNAVAIL; + set_GSSERRS(EINVAL, GSS_S_CRED_UNAVAIL); goto done; } } @@ -364,8 +362,7 @@ uint32_t gssntlm_acquire_cred_from(uint32_t *minor_status, if (cred_usage == GSS_C_INITIATE) { if (name != NULL && name->type != GSSNTLM_NAME_USER) { - retmin = EINVAL; - retmaj = GSS_S_CRED_UNAVAIL; + set_GSSERRS(EINVAL, GSS_S_CRED_UNAVAIL); goto done; } @@ -378,24 +375,24 @@ uint32_t gssntlm_acquire_cred_from(uint32_t *minor_status, } } if (retmin) { - retmaj = GSS_S_CRED_UNAVAIL; + set_GSSERRS(retmin, GSS_S_CRED_UNAVAIL); } } else if (cred_usage == GSS_C_ACCEPT) { if (name != NULL && name->type != GSSNTLM_NAME_SERVER) { - retmin = EINVAL; - retmaj = GSS_S_CRED_UNAVAIL; + set_GSSERRS(EINVAL, GSS_S_CRED_UNAVAIL); goto done; } retmin = get_server_creds(name, cred); if (retmin) { - retmaj = GSS_S_CRED_UNAVAIL; + set_GSSERRS(retmin, GSS_S_CRED_UNAVAIL); } } else { - retmin = EINVAL; - retmaj = GSS_S_CRED_UNAVAIL; + set_GSSERRS(EINVAL, GSS_S_CRED_UNAVAIL); } + set_GSSERRS(0, GSS_S_COMPLETE); + done: if (retmaj) { uint32_t tmpmin; @@ -404,8 +401,8 @@ done: *output_cred_handle = (gss_cred_id_t)cred; if (time_rec) *time_rec = GSS_C_INDEFINITE; } - *minor_status = retmin; - return retmaj; + + return GSSERR(); } uint32_t gssntlm_acquire_cred(uint32_t *minor_status, @@ -479,19 +476,20 @@ uint32_t gssntlm_inquire_cred(uint32_t *minor_status, gss_OID_set *mechanisms) { struct gssntlm_cred *cred; + uint32_t retmin, retmaj; uint32_t maj, min; - if (minor_status == NULL) - return GSS_S_CALL_INACCESSIBLE_WRITE; - *minor_status = 0; - - if (cred_handle == GSS_C_NO_CREDENTIAL) - return GSS_S_NO_CRED; + if (cred_handle == GSS_C_NO_CREDENTIAL) { + set_GSSERRS(0, GSS_S_NO_CRED); + goto done; + } cred = (struct gssntlm_cred *)cred_handle; - if (cred->type == GSSNTLM_CRED_NONE) - return GSS_S_NO_CRED; + if (cred->type == GSSNTLM_CRED_NONE) { + set_GSSERRS(0, GSS_S_NO_CRED); + goto done; + } if (name) { switch (cred->type) { @@ -500,22 +498,31 @@ uint32_t gssntlm_inquire_cred(uint32_t *minor_status, *name = GSS_C_NO_NAME; break; case GSSNTLM_CRED_USER: - maj = gssntlm_duplicate_name(minor_status, + maj = gssntlm_duplicate_name(&min, (gss_name_t)&cred->cred.user.user, name); - if (maj != GSS_S_COMPLETE) return maj; + if (maj != GSS_S_COMPLETE) { + set_GSSERRS(min, maj); + goto done; + } break; case GSSNTLM_CRED_SERVER: - maj = gssntlm_duplicate_name(minor_status, + maj = gssntlm_duplicate_name(&min, (gss_name_t)&cred->cred.server.name, name); - if (maj != GSS_S_COMPLETE) return maj; + if (maj != GSS_S_COMPLETE) { + set_GSSERRS(min, maj); + goto done; + } break; case GSSNTLM_CRED_EXTERNAL: - maj = gssntlm_duplicate_name(minor_status, - (gss_name_t)&cred->cred.external.user, - name); - if (maj != GSS_S_COMPLETE) return maj; + maj = gssntlm_duplicate_name(&min, + (gss_name_t)&cred->cred.external.user, + name); + if (maj != GSS_S_COMPLETE) { + set_GSSERRS(min, maj); + goto done; + } break; } } @@ -530,22 +537,27 @@ uint32_t gssntlm_inquire_cred(uint32_t *minor_status, } if (mechanisms) { - maj = gss_create_empty_oid_set(minor_status, mechanisms); + maj = gss_create_empty_oid_set(&min, mechanisms); if (maj != GSS_S_COMPLETE) { + set_GSSERRS(min, maj); gss_release_name(&min, name); - return maj; + goto done; } - maj = gss_add_oid_set_member(minor_status, + maj = gss_add_oid_set_member(&min, discard_const(&gssntlm_oid), mechanisms); if (maj != GSS_S_COMPLETE) { + set_GSSERRS(min, maj); gss_release_oid_set(&min, mechanisms); gss_release_name(&min, name); - return maj; + goto done; } } - return GSS_S_COMPLETE; + set_GSSERRS(0, GSS_S_COMPLETE); + +done: + return GSSERR(); } uint32_t gssntlm_inquire_cred_by_mech(uint32_t *minor_status, @@ -558,11 +570,13 @@ uint32_t gssntlm_inquire_cred_by_mech(uint32_t *minor_status, { gss_cred_usage_t usage; uint32_t lifetime; - uint32_t maj; + uint32_t retmaj; + uint32_t retmin; + uint32_t maj, min; - maj = gssntlm_inquire_cred(minor_status, cred_handle, name, + maj = gssntlm_inquire_cred(&min, cred_handle, name, &lifetime, &usage, NULL); - if (maj != GSS_S_COMPLETE) return maj; + if (maj != GSS_S_COMPLETE) return GSSERRS(min, maj); switch (usage) { case GSS_C_INITIATE: @@ -578,10 +592,9 @@ uint32_t gssntlm_inquire_cred_by_mech(uint32_t *minor_status, if (acceptor_lifetime) *acceptor_lifetime = lifetime; break; default: - *minor_status = EINVAL; - return GSS_S_FAILURE; + return GSSERRS(EINVAL, GSS_S_FAILURE); } if (cred_usage) *cred_usage = usage; - return GSS_S_COMPLETE; + return GSSERRS(0, GSS_S_COMPLETE); } diff --git a/src/gss_err.c b/src/gss_err.c index 321ed90..b350a19 100644 --- a/src/gss_err.c +++ b/src/gss_err.c @@ -18,18 +18,18 @@ uint32_t gssntlm_display_status(uint32_t *minor_status, uint32_t *message_context, gss_buffer_t status_string) { + uint32_t retmaj; + uint32_t retmin; /* if you can't say it in ~6 lines of text we don't bother */ char buf[512]; int err; - if (!minor_status || !status_string) { - *minor_status = EINVAL; - return GSS_S_CALL_INACCESSIBLE_READ; + if (!status_string) { + return GSSERRS(EINVAL, GSS_S_CALL_INACCESSIBLE_READ); } if (status_type != GSS_C_MECH_CODE) { - *minor_status = EINVAL; - return GSS_S_BAD_STATUS; + return GSSERRS(EINVAL, GSS_S_BAD_STATUS); } *minor_status = 0; @@ -80,10 +80,9 @@ done: if (!status_string->value) { status_string->value = strdup(UNKNOWN_ERROR); if (!status_string->value) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; + return GSSERRS(ENOMEM, GSS_S_FAILURE); } } status_string->length = strlen(status_string->value); - return GSS_S_COMPLETE; + return GSSERRS(0, GSS_S_COMPLETE); } diff --git a/src/gss_names.c b/src/gss_names.c index 3c6f5a2..1c2f25e 100644 --- a/src/gss_names.c +++ b/src/gss_names.c @@ -32,25 +32,25 @@ #include "gss_ntlmssp.h" -static uint32_t string_split(uint32_t *retmin, char sep, +static uint32_t string_split(uint32_t *minor_status, char sep, const char *str, size_t len, char **s1, char **s2) { uint32_t retmaj; + uint32_t retmin; char *r1 = NULL; char *r2 = NULL; const char *p; size_t l; p = memchr(str, sep, len); - if (!p) return GSS_S_UNAVAILABLE; + if (!p) return GSSERRS(0, GSS_S_UNAVAILABLE); if (s1) { l = p - str; r1 = strndup(str, l); if (!r1) { - *retmin = ENOMEM; - retmaj = GSS_S_FAILURE; + set_GSSERR(ENOMEM); goto done; } } @@ -59,13 +59,12 @@ static uint32_t string_split(uint32_t *retmin, char sep, l = len - (p - str); r2 = strndup(p, l); if (!r2) { - *retmin = ENOMEM; - retmaj = GSS_S_FAILURE; + set_GSSERR(ENOMEM); goto done; } } - retmaj = GSS_S_COMPLETE; + set_GSSERRS(0, GSS_S_COMPLETE); done: if (retmaj) { @@ -75,20 +74,21 @@ done: if (s1) *s1 = r1; if (s2) *s2 = r2; } - return retmaj; + return GSSERR(); } #define MAX_NAME_LEN 1024 -static uint32_t get_enterprise_name(uint32_t *retmin, +static uint32_t get_enterprise_name(uint32_t *minor_status, const char *str, size_t len, char **username) { + uint32_t retmaj; + uint32_t retmin; char *buf; char *e; if (len > MAX_NAME_LEN) { - *retmin = EINVAL; - return GSS_S_BAD_NAME; + return GSSERRS(EINVAL, GSS_S_BAD_NAME); } buf = alloca(len + 1); @@ -96,35 +96,42 @@ static uint32_t get_enterprise_name(uint32_t *retmin, buf[len] = '\0'; e = strstr(buf, "\\@"); - if (!e) return GSS_S_UNAVAILABLE; + if (!e) return GSSERRS(0, GSS_S_UNAVAILABLE); /* remove escape */ memmove(e, e + 1, len - (e - buf)); *username = strdup(buf); if (NULL == *username) { - *retmin = ENOMEM; - return GSS_S_FAILURE; + set_GSSERR(ENOMEM); + goto done; } - return GSS_S_COMPLETE; + set_GSSERRS(0, GSS_S_COMPLETE); + +done: + return GSSERR(); } -static uint32_t uid_to_name(uint32_t *retmin, uid_t uid, char **name) +static uint32_t uid_to_name(uint32_t *minor_status, uid_t uid, char **name) { + uint32_t retmaj; + uint32_t retmin; struct passwd *pw; pw = getpwuid(uid); if (pw) { - *retmin = ENOENT; - return GSS_S_FAILURE; + return GSSERRS(ENOENT, GSS_S_FAILURE); } *name = strdup(pw->pw_name); if (!*name) { - *retmin = ENOMEM; - return GSS_S_FAILURE; + set_GSSERR(ENOMEM); + goto done; } - return GSS_S_COMPLETE; + set_GSSERRS(0, GSS_S_COMPLETE); + +done: + return GSSERR(); } uint32_t gssntlm_import_name_by_mech(uint32_t *minor_status, @@ -137,18 +144,18 @@ uint32_t gssntlm_import_name_by_mech(uint32_t *minor_status, char struid[12] = { 0 }; uid_t uid; struct gssntlm_name *name = NULL; - uint32_t retmaj = GSS_S_FAILURE; - uint32_t retmin = 0; + uint32_t retmaj; + uint32_t retmin; /* TODO: check mech_type == gssntlm_oid */ if (mech_type == GSS_C_NO_OID) { - return GSS_S_CALL_INACCESSIBLE_READ; + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_READ); } name = calloc(1, sizeof(struct gssntlm_name)); if (!name) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; + set_GSSERR(ENOMEM); + goto done; } /* treat null OID like NT_USER_NAME */ @@ -174,16 +181,15 @@ uint32_t gssntlm_import_name_by_mech(uint32_t *minor_status, * the local host name */ retmin = gethostname(hostname, HOST_NAME_MAX); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } hostname[HOST_NAME_MAX] = '\0'; name->data.server.name = strdup(hostname); if (!name->data.server.name) { - retmin = ENOMEM; - retmaj = GSS_S_FAILURE; + set_GSSERR(ENOMEM); } - retmaj = GSS_S_COMPLETE; + set_GSSERRS(0, GSS_S_COMPLETE); } else if (gss_oid_equal(input_name_type, GSS_C_NT_USER_NAME)) { @@ -223,8 +229,7 @@ uint32_t gssntlm_import_name_by_mech(uint32_t *minor_status, name->data.user.name = strndup(input_name_buffer->value, input_name_buffer->length); if (!name->data.user.name) { - retmin = ENOMEM; - retmaj = GSS_S_FAILURE; + set_GSSERR(ENOMEM); } retmaj = GSS_S_COMPLETE; } else if (gss_oid_equal(input_name_type, GSS_C_NT_MACHINE_UID_NAME)) { @@ -240,8 +245,7 @@ uint32_t gssntlm_import_name_by_mech(uint32_t *minor_status, name->data.user.domain = NULL; if (input_name_buffer->length > 12) { - retmin = EINVAL; - retmaj = GSS_S_FAILURE; + set_GSSERR(EINVAL); goto done; } memcpy(struid, input_name_buffer->value, input_name_buffer->length); @@ -249,17 +253,18 @@ uint32_t gssntlm_import_name_by_mech(uint32_t *minor_status, errno = 0; uid = strtol(struid, NULL, 10); if (errno) { - retmin = errno; - retmaj = GSS_S_FAILURE; + set_GSSERR(errno); goto done; } retmaj = uid_to_name(&retmin, uid, &name->data.user.name); } else if (gss_oid_equal(input_name_type, GSS_C_NT_ANONYMOUS)) { name->type = GSSNTLM_NAME_ANON; - retmaj = GSS_S_COMPLETE; + set_GSSERRS(0, GSS_S_COMPLETE); } else if (gss_oid_equal(input_name_type, GSS_C_NT_EXPORT_NAME)) { /* TODO */ - retmaj = GSS_S_UNAVAILABLE; + set_GSSERRS(0, GSS_S_UNAVAILABLE); + } else { + set_GSSERRS(EINVAL, GSS_S_BAD_MECH); } done: @@ -269,8 +274,7 @@ done: } else { *output_name = (gss_name_t)name; } - *minor_status = retmin; - return retmaj; + return GSSERR(); } uint32_t gssntlm_import_name(uint32_t *minor_status, @@ -341,33 +345,39 @@ uint32_t gssntlm_duplicate_name(uint32_t *minor_status, struct gssntlm_name *in; struct gssntlm_name *out; uint32_t retmin; - - *minor_status = 0; + uint32_t retmaj; if (input_name == GSS_C_NO_NAME || dest_name == NULL) { - return GSS_S_CALL_INACCESSIBLE_READ; + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_READ); } in = (struct gssntlm_name *)input_name; if (in->type == GSSNTLM_NAME_NULL) { *dest_name = GSS_C_NO_NAME; - return GSS_S_COMPLETE; + return GSSERRS(0, GSS_S_COMPLETE); } out = calloc(1, sizeof(struct gssntlm_name)); if (!out) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; + set_GSSERR(ENOMEM); + goto done; } retmin = gssntlm_copy_name(in, out); + if (retmin) { + set_GSSERR(retmin); + goto done; + } - *minor_status = retmin; - if (retmin) return GSS_S_FAILURE; + set_GSSERRS(0, GSS_S_COMPLETE); +done: + if (retmaj) { + safefree(out); + } *dest_name = (gss_name_t)out; - return GSS_S_COMPLETE; + return GSSERR(); } void gssntlm_int_release_name(struct gssntlm_name *name) @@ -393,12 +403,17 @@ void gssntlm_int_release_name(struct gssntlm_name *name) uint32_t gssntlm_release_name(uint32_t *minor_status, gss_name_t *input_name) { - if (!input_name) return GSS_S_CALL_INACCESSIBLE_READ; + uint32_t retmaj; + uint32_t retmin; + + if (!input_name) { + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_READ); + } gssntlm_int_release_name((struct gssntlm_name *)*input_name); safefree(*input_name); - return GSS_S_COMPLETE; + return GSSERRS(0, GSS_S_COMPLETE); } uint32_t gssntlm_display_name(uint32_t *minor_status, @@ -408,12 +423,12 @@ uint32_t gssntlm_display_name(uint32_t *minor_status, { struct gssntlm_name *in; gss_buffer_t out; + uint32_t retmaj; + uint32_t retmin; int ret; - *minor_status = 0; - if (input_name == GSS_C_NO_NAME || output_name_buffer == NULL) { - return GSS_S_CALL_INACCESSIBLE_READ; + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_READ); } in = (struct gssntlm_name *)input_name; @@ -421,12 +436,12 @@ uint32_t gssntlm_display_name(uint32_t *minor_status, switch (in->type) { case GSSNTLM_NAME_NULL: - return GSS_S_BAD_NAME; + return GSSERRS(0, GSS_S_BAD_NAME); case GSSNTLM_NAME_ANON: out->value = strdup("NT AUTHORITY\\ANONYMOUS LOGON"); if (!out->value) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; + set_GSSERR(ENOMEM); + goto done; } out->length = strlen(out->value) + 1; if (output_name_type) { @@ -444,8 +459,8 @@ uint32_t gssntlm_display_name(uint32_t *minor_status, out->value = strdup(in->data.user.name); } if (!out->value) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; + set_GSSERR(ENOMEM); + goto done; } out->length = strlen(out->value) + 1; if (output_name_type) { @@ -455,8 +470,8 @@ uint32_t gssntlm_display_name(uint32_t *minor_status, case GSSNTLM_NAME_SERVER: out->value = strdup(in->data.server.name); if (!out->value) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; + set_GSSERR(ENOMEM); + goto done; } out->length = strlen(out->value) + 1; if (output_name_type) { @@ -465,7 +480,10 @@ uint32_t gssntlm_display_name(uint32_t *minor_status, break; } - return GSS_S_COMPLETE; + set_GSSERRS(0, GSS_S_COMPLETE); + +done: + return GSSERR(); } #define PWBUFLEN 1024 @@ -479,13 +497,14 @@ uint32_t gssntlm_localname(uint32_t *minor_status, char *uname = NULL; char pwbuf[PWBUFLEN]; struct passwd pw, *res; - uint32_t min = 0; + uint32_t retmaj; + uint32_t retmin; int ret; in = (struct gssntlm_name *)name; if (in->type != GSSNTLM_NAME_USER) { - *minor_status = EINVAL; - return GSS_S_FAILURE; + set_GSSERR(EINVAL); + goto done; } /* TODO: hook up with winbindd/sssd for name resolution ? */ @@ -494,12 +513,12 @@ uint32_t gssntlm_localname(uint32_t *minor_status, ret = asprintf(&uname, "%s\\%s", in->data.user.domain, in->data.user.name); if (ret == -1) { - min = ENOMEM; + set_GSSERR(ENOMEM); goto done; } ret = getpwnam_r(uname, &pw, pwbuf, PWBUFLEN, &res); if (ret) { - min = ret; + set_GSSERR(ret); goto done; } safefree(uname); @@ -510,25 +529,26 @@ uint32_t gssntlm_localname(uint32_t *minor_status, if (uname == NULL) { ret = getpwnam_r(in->data.user.name, &pw, pwbuf, PWBUFLEN, &res); if (ret != 0 || res == NULL) { - min = ret; + set_GSSERR(ret); goto done; } uname = strdup(res->pw_name); } if (!uname) { - min = ENOMEM; + set_GSSERR(ENOMEM); goto done; } + set_GSSERRS(0, GSS_S_COMPLETE); + done: - *minor_status = min; - if (min) { - free(uname); - return GSS_S_FAILURE; - } - localname->value = uname; - localname->length = strlen(uname) + 1; - return GSS_S_COMPLETE; + if (retmaj) { + safefree(uname); + } else { + localname->value = uname; + localname->length = strlen(uname) + 1; + } + return GSSERR(); } uint32_t netbios_get_names(char *computer_name, diff --git a/src/gss_ntlmssp.h b/src/gss_ntlmssp.h index 33b3279..ee38c6f 100644 --- a/src/gss_ntlmssp.h +++ b/src/gss_ntlmssp.h @@ -156,6 +156,21 @@ struct gssntlm_ctx { time_t expiration_time; }; +#define set_GSSERRS(min, maj) \ + (void)DEBUG_GSS_ERRORS((retmaj = (maj)), (retmin = (min))) +#define set_GSSERR(min) set_GSSERRS((min), GSS_S_FAILURE) + +static inline uint32_t gssntlmssp_ret_err(uint32_t *s, uint32_t n, uint32_t j) +{ + if (!s) return GSS_S_CALL_INACCESSIBLE_WRITE; + *s = n; + return j; +} +#define GSSERR() gssntlmssp_ret_err(minor_status, retmin, retmaj) +#define GSSERRS(min, maj) \ + DEBUG_GSS_ERRORS((retmaj = (maj)), (retmin = (min))) ? 0 : \ + gssntlmssp_ret_err(minor_status, retmin, retmaj) + uint8_t gssntlm_required_security(int security_level, struct gssntlm_ctx *ctx); void gssntlm_set_role(struct gssntlm_ctx *ctx, diff --git a/src/gss_sec_ctx.c b/src/gss_sec_ctx.c index 75f6b43..f16d613 100644 --- a/src/gss_sec_ctx.c +++ b/src/gss_sec_ctx.c @@ -57,29 +57,28 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status, ctx = (struct gssntlm_ctx *)(*context_handle); /* reset return values */ - *minor_status = 0; if (actual_mech_type) *actual_mech_type = NULL; if (ret_flags) *ret_flags = 0; if (time_rec) *time_rec = 0; if (output_token == GSS_C_NO_BUFFER) { - return GSS_S_CALL_INACCESSIBLE_WRITE; + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_WRITE); } if (target_name) { server = (struct gssntlm_name *)target_name; if (server->type != GSSNTLM_NAME_SERVER) { - return GSS_S_BAD_NAMETYPE; + return GSSERRS(0, GSS_S_BAD_NAMETYPE); } if (!server->data.server.name || !server->data.server.name[0]) { - return GSS_S_BAD_NAME; + return GSSERRS(0, GSS_S_BAD_NAME); } } if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) { if (req_flags & GSS_C_ANON_FLAG) { - retmaj = GSS_S_UNAVAILABLE; + set_GSSERRS(0, GSS_S_UNAVAILABLE); goto done; } else { retmaj = gssntlm_acquire_cred(&retmin, @@ -93,8 +92,7 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status, cred = (struct gssntlm_cred *)claimant_cred_handle; if (cred->type != GSSNTLM_CRED_USER && cred->type != GSSNTLM_CRED_EXTERNAL) { - retmin = EINVAL; - retmaj = GSS_S_CRED_UNAVAIL; + set_GSSERRS(EINVAL, GSS_S_CRED_UNAVAIL); goto done; } } @@ -104,22 +102,21 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status, /* first call */ ctx = calloc(1, sizeof(struct gssntlm_ctx)); if (!ctx) { - retmin = ENOMEM; - retmaj = GSS_S_FAILURE; + set_GSSERR(ENOMEM); goto done; } retmin = gssntlm_copy_name(&cred->cred.user.user, &ctx->source_name); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } if (server) { retmin = gssntlm_copy_name(server, &ctx->target_name); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } } @@ -176,22 +173,20 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status, computer_name = strdup(client_name->data.server.name); if (!computer_name) { - retmin = ENOMEM; - retmaj = GSS_S_FAILURE; + set_GSSERR(ENOMEM); goto done; } retmin = netbios_get_names(computer_name, &nb_computer_name, &nb_domain_name); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } ctx->workstation = strdup(nb_computer_name); if (!ctx->workstation) { - retmin = ENOMEM; - retmaj = GSS_S_FAILURE; + set_GSSERR(ENOMEM); goto done; } @@ -200,7 +195,7 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status, lm_compat_lvl = gssntlm_get_lm_compatibility_level(); ctx->sec_req = gssntlm_required_security(lm_compat_lvl, ctx); if (ctx->sec_req == 0xff) { - retmaj = GSS_S_FAILURE; + set_GSSERR(EINVAL); goto done; } if (!gssntlm_sec_lm_ok(ctx)) { @@ -213,7 +208,7 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status, retmin = ntlm_init_ctx(&ctx->ntlm); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } @@ -231,35 +226,33 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status, /* and return the ball */ ctx->stage = NTLMSSP_STAGE_NEGOTIATE; - retmaj = GSS_S_CONTINUE_NEEDED; + set_GSSERRS(0, GSS_S_CONTINUE_NEEDED); goto done; } } else { if (input_token && input_token->length != 0) { - retmin = EINVAL; - retmaj = GSS_S_DEFECTIVE_TOKEN; + set_GSSERRS(EINVAL, GSS_S_DEFECTIVE_TOKEN); goto done; } retmin = ntlm_encode_neg_msg(ctx->ntlm, ctx->neg_flags, NULL, NULL, &ctx->nego_msg); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } output_token->value = malloc(ctx->nego_msg.length); if (!output_token->value) { - retmin = ENOMEM; - retmaj = GSS_S_FAILURE; + set_GSSERR(ENOMEM); goto done; } memcpy(output_token->value, ctx->nego_msg.data, ctx->nego_msg.length); output_token->length = ctx->nego_msg.length; ctx->stage = NTLMSSP_STAGE_NEGOTIATE; - retmaj = GSS_S_CONTINUE_NEEDED; + set_GSSERRS(0, GSS_S_CONTINUE_NEEDED); goto done; } @@ -270,21 +263,19 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status, if (ctx == NULL) { /* this should not happen */ - retmin = EFAULT; - retmaj = GSS_S_FAILURE; + set_GSSERR(EFAULT); goto done; } else { if (!gssntlm_role_is_client(ctx)) { - retmaj = GSS_S_NO_CONTEXT; + set_GSSERRS(0, GSS_S_NO_CONTEXT); goto done; } ctx->chal_msg.data = malloc(input_token->length); if (!ctx->chal_msg.data) { - retmin = ENOMEM; - retmaj = GSS_S_FAILURE; + set_GSSERR(ENOMEM); goto done; } memcpy(ctx->chal_msg.data, input_token->value, input_token->length); @@ -292,13 +283,13 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status, retmin = ntlm_decode_msg_type(ctx->ntlm, &ctx->chal_msg, &msg_type); if (retmin) { - retmaj = GSS_S_DEFECTIVE_TOKEN; + set_GSSERRS(retmin, GSS_S_DEFECTIVE_TOKEN); goto done; } if (msg_type != CHALLENGE_MESSAGE || ctx->stage != NTLMSSP_STAGE_NEGOTIATE) { - retmaj = GSS_S_NO_CONTEXT; + set_GSSERRS(0, GSS_S_NO_CONTEXT); goto done; } @@ -308,7 +299,7 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status, retmin = ntlm_decode_chal_msg(ctx->ntlm, &ctx->chal_msg, &in_flags, &trgt_name, &challenge, &target_info); if (retmin) { - retmaj = GSS_S_DEFECTIVE_TOKEN; + set_GSSERRS(retmin, GSS_S_DEFECTIVE_TOKEN); goto done; } @@ -336,36 +327,36 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status, if ((ctx->neg_flags & NTLMSSP_NEGOTIATE_128) && (!(ctx->neg_flags & NTLMSSP_NEGOTIATE_56)) && (!(in_flags & NTLMSSP_NEGOTIATE_128))) { - retmaj = GSS_S_UNAVAILABLE; + set_GSSERR(0); goto done; } if ((ctx->neg_flags & NTLMSSP_NEGOTIATE_SEAL) && (!(in_flags & NTLMSSP_NEGOTIATE_SEAL))) { - retmaj = GSS_S_FAILURE; + set_GSSERR(0); goto done; } if ((ctx->neg_flags & NTLMSSP_NEGOTIATE_SIGN) && (!(in_flags & NTLMSSP_NEGOTIATE_SIGN))) { - retmaj = GSS_S_FAILURE; + set_GSSERR(0); goto done; } if (!(in_flags & (NTLMSSP_NEGOTIATE_OEM | NTLMSSP_NEGOTIATE_UNICODE))) { /* no common understanding */ - retmaj = GSS_S_FAILURE; + set_GSSERR(0); goto done; } if (ctx->gss_flags & GSS_C_DATAGRAM_FLAG) { if (!(in_flags & NTLMSSP_NEGOTIATE_DATAGRAM)) { /* no common understanding */ - retmaj = GSS_S_FAILURE; + set_GSSERR(0); goto done; } if (!(in_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) { /* no common understanding */ - retmaj = GSS_S_FAILURE; + set_GSSERR(0); goto done; } if ((in_flags & NTLMSSP_NEGOTIATE_OEM) && @@ -384,7 +375,7 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status, if (in_flags & (NTLMSSP_NEGOTIATE_TARGET_INFO | NTLMSSP_TARGET_TYPE_SERVER | NTLMSSP_TARGET_TYPE_DOMAIN)) { - retmaj = GSS_S_FAILURE; + set_GSSERR(0); goto done; } else { in_flags &= ~NTLMSSP_NEGOTIATE_UNICODE; @@ -405,7 +396,7 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status, &ctx->exported_session_key, &ctx->crypto_state); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } } @@ -421,8 +412,7 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status, output_token->value = malloc(ctx->auth_msg.length); if (!output_token->value) { - retmin = ENOMEM; - retmaj = GSS_S_FAILURE; + set_GSSERR(ENOMEM); goto done; } memcpy(output_token->value, ctx->auth_msg.data, ctx->auth_msg.length); @@ -432,14 +422,13 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status, ctx->expiration_time = time(NULL) + MAX_CHALRESP_LIFETIME; ctx->int_flags |= NTLMSSP_CTX_FLAG_ESTABLISHED; - retmaj = GSS_S_COMPLETE; + set_GSSERRS(0, GSS_S_COMPLETE); } done: if ((retmaj != GSS_S_COMPLETE) && (retmaj != GSS_S_CONTINUE_NEEDED)) { gssntlm_delete_sec_context(&tmpmin, (gss_ctx_id_t *)&ctx, NULL); - *minor_status = retmin; } else { if (ret_flags) *ret_flags = ctx->gss_flags; if (time_rec) *time_rec = GSS_C_INDEFINITE; @@ -455,7 +444,8 @@ done: safefree(nb_domain_name); safefree(trgt_name); ntlm_free_buffer_data(&target_info); - return retmaj; + + return GSSERR(); } uint32_t gssntlm_delete_sec_context(uint32_t *minor_status, @@ -463,12 +453,18 @@ uint32_t gssntlm_delete_sec_context(uint32_t *minor_status, gss_buffer_t output_token) { struct gssntlm_ctx *ctx; + uint32_t retmin; + uint32_t retmaj; int ret; - *minor_status = 0; - - if (!context_handle) return GSS_S_CALL_INACCESSIBLE_READ; - if (*context_handle == NULL) return GSS_S_NO_CONTEXT; + if (!context_handle) { + set_GSSERRS(0, GSS_S_CALL_INACCESSIBLE_READ); + goto done; + } + if (*context_handle == NULL) { + set_GSSERRS(0, GSS_S_NO_CONTEXT); + goto done; + } ctx = (struct gssntlm_ctx *)*context_handle; @@ -492,11 +488,9 @@ uint32_t gssntlm_delete_sec_context(uint32_t *minor_status, safezero((uint8_t *)ctx, sizeof(struct gssntlm_ctx)); safefree(*context_handle); - if (ret) { - *minor_status = ret; - return GSS_S_FAILURE; - } - return GSS_S_COMPLETE; + set_GSSERRS(ret, ret ? GSS_S_FAILURE : GSS_S_COMPLETE); +done: + return GSSERR(); } uint32_t gssntlm_context_time(uint32_t *minor_status, @@ -505,20 +499,25 @@ uint32_t gssntlm_context_time(uint32_t *minor_status, { struct gssntlm_ctx *ctx; time_t now; + uint32_t retmin; uint32_t retmaj; - *minor_status = 0; - if (context_handle == GSS_C_NO_CONTEXT) { - return GSS_S_CALL_INACCESSIBLE_READ; + set_GSSERRS(0, GSS_S_CALL_INACCESSIBLE_READ); + goto done; } ctx = (struct gssntlm_ctx *)context_handle; retmaj = gssntlm_context_is_valid(ctx, &now); - if (retmaj) return retmaj; + if (retmaj) { + set_GSSERRS(0, retmaj); + goto done; + } *time_rec = ctx->expiration_time - now; - return GSS_S_COMPLETE; + set_GSSERRS(0, GSS_S_COMPLETE); +done: + return GSSERR(); } uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, @@ -556,8 +555,8 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, char *wks_name = NULL; struct gssntlm_name *gss_usrname = NULL; struct gssntlm_cred *usr_cred = NULL; - uint32_t retmin = 0; - uint32_t retmaj = 0; + uint32_t retmin; + uint32_t retmaj; uint32_t tmpmin; uint32_t in_flags; uint32_t msg_type; @@ -565,13 +564,13 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, struct ntlm_buffer unhashed_cb = { 0 }; struct ntlm_buffer av_cb = { 0 }; - if (context_handle == NULL) return GSS_S_CALL_INACCESSIBLE_READ; + if (context_handle == NULL) { + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_READ); + } if (output_token == GSS_C_NO_BUFFER) { - return GSS_S_CALL_INACCESSIBLE_WRITE; + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_WRITE); } - /* reset return values */ - *minor_status = 0; if (src_name) *src_name = GSS_C_NO_NAME; if (mech_type) *mech_type = GSS_C_NO_OID; if (ret_flags) *ret_flags = 0; @@ -581,11 +580,11 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, if (acceptor_cred_handle) { cred = (struct gssntlm_cred *)acceptor_cred_handle; if (cred->type != GSSNTLM_CRED_SERVER) { - retmaj = GSS_S_DEFECTIVE_CREDENTIAL; + set_GSSERRS(0, GSS_S_DEFECTIVE_CREDENTIAL); goto done; } if (cred->cred.server.name.type != GSSNTLM_NAME_SERVER) { - retmaj = GSS_S_DEFECTIVE_CREDENTIAL; + set_GSSERRS(0, GSS_S_DEFECTIVE_CREDENTIAL); goto done; } retmaj = gssntlm_duplicate_name(&retmin, @@ -599,8 +598,7 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, /* first call */ ctx = calloc(1, sizeof(struct gssntlm_ctx)); if (!ctx) { - retmin = ENOMEM; - retmaj = GSS_S_FAILURE; + set_GSSERR(ENOMEM); goto done; } @@ -619,28 +617,26 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, retmin = gssntlm_copy_name(server_name, &ctx->target_name); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } computer_name = strdup(server_name->data.server.name); if (!computer_name) { - retmin = ENOMEM; - retmaj = GSS_S_FAILURE; + set_GSSERR(ENOMEM); goto done; } retmin = netbios_get_names(computer_name, &nb_computer_name, &nb_domain_name); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } ctx->workstation = strdup(nb_computer_name); if (!ctx->workstation) { - retmin = ENOMEM; - retmaj = GSS_S_FAILURE; + set_GSSERR(ENOMEM); goto done; } @@ -649,7 +645,7 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, lm_compat_lvl = gssntlm_get_lm_compatibility_level(); ctx->sec_req = gssntlm_required_security(lm_compat_lvl, ctx); if (ctx->sec_req == 0xff) { - retmaj = GSS_S_FAILURE; + set_GSSERR(EINVAL); goto done; } @@ -666,15 +662,14 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, retmin = ntlm_init_ctx(&ctx->ntlm); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } if (input_token && input_token->length != 0) { ctx->nego_msg.data = malloc(input_token->length); if (!ctx->nego_msg.data) { - retmin = ENOMEM; - retmaj = GSS_S_FAILURE; + set_GSSERR(ENOMEM); goto done; } memcpy(ctx->nego_msg.data, input_token->value, input_token->length); @@ -682,14 +677,14 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, retmin = ntlm_decode_msg_type(ctx->ntlm, &ctx->nego_msg, &msg_type); if (retmin || (msg_type != NEGOTIATE_MESSAGE)) { - retmaj = GSS_S_DEFECTIVE_TOKEN; + set_GSSERRS(retmin, GSS_S_DEFECTIVE_TOKEN); goto done; } retmin = ntlm_decode_neg_msg(ctx->ntlm, &ctx->nego_msg, &in_flags, NULL, NULL); if (retmin) { - retmaj = GSS_S_DEFECTIVE_TOKEN; + set_GSSERRS(retmin, GSS_S_DEFECTIVE_TOKEN); goto done; } @@ -711,7 +706,7 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, ctx->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM; } else if (!(ctx->neg_flags & NTLMSSP_NEGOTIATE_OEM)) { /* no agreement */ - retmaj = GSS_S_FAILURE; + set_GSSERR(0); goto done; } @@ -738,7 +733,7 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, challenge.length = 8; retmin = RAND_BUFFER(&challenge); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } @@ -753,7 +748,7 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, NULL, NULL, NULL, &target_info); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } @@ -769,7 +764,7 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, chal_target_name, &challenge, &target_info, &ctx->chal_msg); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } @@ -777,8 +772,7 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, output_token->value = malloc(ctx->chal_msg.length); if (!output_token->value) { - retmin = ENOMEM; - retmaj = GSS_S_FAILURE; + set_GSSERR(ENOMEM); goto done; } memcpy(output_token->value, ctx->chal_msg.data, ctx->chal_msg.length); @@ -790,22 +784,19 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, ctx = (struct gssntlm_ctx *)(*context_handle); if (!gssntlm_role_is_server(ctx)) { - retmin = EINVAL; - retmaj = GSS_S_NO_CONTEXT; + set_GSSERRS(EINVAL, GSS_S_NO_CONTEXT); goto done; } if ((input_token == GSS_C_NO_BUFFER) || (input_token->length == 0)) { - retmin = EINVAL; - retmaj = GSS_S_DEFECTIVE_TOKEN; + set_GSSERRS(EINVAL, GSS_S_DEFECTIVE_TOKEN); goto done; } ctx->auth_msg.data = malloc(input_token->length); if (!ctx->auth_msg.data) { - retmin = ENOMEM; - retmaj = GSS_S_FAILURE; + set_GSSERR(ENOMEM); goto done; } memcpy(ctx->auth_msg.data, input_token->value, input_token->length); @@ -813,13 +804,13 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, retmin = ntlm_decode_msg_type(ctx->ntlm, &ctx->auth_msg, &msg_type); if (retmin) { - retmaj = GSS_S_DEFECTIVE_TOKEN; + set_GSSERRS(retmin, GSS_S_DEFECTIVE_TOKEN); goto done; } if (msg_type != AUTHENTICATE_MESSAGE || ctx->stage != NTLMSSP_STAGE_CHALLENGE) { - retmaj = GSS_S_NO_CONTEXT; + set_GSSERRS(0, GSS_S_NO_CONTEXT); goto done; } @@ -829,7 +820,7 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, &dom_name, &usr_name, &wks_name, &enc_sess_key, &target_info, &mic); if (retmin) { - retmaj = GSS_S_DEFECTIVE_TOKEN; + set_GSSERRS(retmin, GSS_S_DEFECTIVE_TOKEN); goto done; } @@ -839,15 +830,14 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, NULL, NULL, &av_flags, NULL, NULL, &av_cb); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } } if ((ctx->neg_flags & NTLMSSP_NEGOTIATE_DATAGRAM) && !(ctx->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) { - retmin = EINVAL; - retmaj = GSS_S_DEFECTIVE_TOKEN; + set_GSSERRS(EINVAL, GSS_S_DEFECTIVE_TOKEN); goto done; } @@ -857,8 +847,7 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, (lm_chal_resp.length == 0))) { /* Anonymous auth */ /* FIXME: not supported for now */ - retmin = EINVAL; - retmaj = GSS_S_FAILURE; + set_GSSERR(EINVAL); goto done; } else { @@ -870,8 +859,7 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, if (!dom_name) { dom_name = strdup(""); if (!dom_name) { - retmin = ENOMEM; - retmaj = GSS_S_FAILURE; + set_GSSERR(ENOMEM); goto done; } } @@ -879,8 +867,7 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, ulen = strlen(usr_name); dlen = strlen(dom_name); if (ulen + dlen + 2 > 1024) { - retmin = EINVAL; - retmaj = GSS_S_FAILURE; + set_GSSERR(EINVAL); goto done; } strncpy(useratdom, usr_name, ulen); @@ -911,14 +898,13 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, /* We can't handle winbind credentials yet */ if (usr_cred->type != GSSNTLM_CRED_USER && usr_cred->type != GSSNTLM_CRED_EXTERNAL) { - retmin = EINVAL; - retmaj = GSS_S_CRED_UNAVAIL; + set_GSSERRS(EINVAL, GSS_S_CRED_UNAVAIL); goto done; } retmin = gssntlm_copy_name(gss_usrname, &ctx->source_name); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } @@ -936,7 +922,7 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, &encrypted_random_session_key, &ctx->exported_session_key); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } } else { @@ -949,7 +935,7 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, &ctx->nego_msg, &ctx->chal_msg, &ctx->auth_msg, &mic); if (retmin) { - retmaj = GSS_S_DEFECTIVE_TOKEN; + set_GSSERRS(retmin, GSS_S_DEFECTIVE_TOKEN); goto done; } } @@ -960,8 +946,7 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, input_chan_bindings->acceptor_addrtype != 0 || input_chan_bindings->acceptor_address.length != 0 || input_chan_bindings->application_data.length == 0) { - retmin = EINVAL; - retmaj = GSS_S_BAD_BINDINGS; + set_GSSERRS(EINVAL, GSS_S_BAD_BINDINGS); goto done; } unhashed_cb.length = input_chan_bindings->application_data.length; @@ -970,7 +955,7 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, /* TODO: optionally allow to ignore CBT if av_cb is null ? */ retmin = ntlm_verify_channel_bindings(&unhashed_cb, &av_cb); if (retmin) { - retmaj = GSS_S_DEFECTIVE_TOKEN; + set_GSSERRS(retmin, GSS_S_DEFECTIVE_TOKEN); goto done; } } @@ -981,7 +966,7 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, &ctx->exported_session_key, &ctx->crypto_state); if (retmin) { - retmaj = GSS_S_FAILURE; + set_GSSERR(retmin); goto done; } } @@ -990,15 +975,13 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, retmaj = gssntlm_duplicate_name(&retmin, (gss_name_t)&ctx->source_name, src_name); - if (retmaj) { - goto done; - } + if (retmaj) goto done; } ctx->stage = NTLMSSP_STAGE_DONE; ctx->expiration_time = time(NULL) + MAX_CHALRESP_LIFETIME; ctx->int_flags |= NTLMSSP_CTX_FLAG_ESTABLISHED; - retmaj = GSS_S_COMPLETE; + set_GSSERRS(0, GSS_S_COMPLETE); } done: @@ -1006,7 +989,6 @@ done: if ((retmaj != GSS_S_COMPLETE) && (retmaj != GSS_S_CONTINUE_NEEDED)) { gssntlm_delete_sec_context(&tmpmin, (gss_ctx_id_t *)&ctx, NULL); - *minor_status = retmin; } else { if (ret_flags) *ret_flags = ctx->gss_flags; if (time_rec) *time_rec = GSS_C_INDEFINITE; @@ -1023,7 +1005,8 @@ done: ntlm_free_buffer_data(&lm_chal_resp); ntlm_free_buffer_data(&enc_sess_key); ntlm_free_buffer_data(&target_info); - return retmaj; + + return GSSERR(); } uint32_t gssntlm_inquire_context(uint32_t *minor_status, @@ -1041,23 +1024,23 @@ uint32_t gssntlm_inquire_context(uint32_t *minor_status, uint32_t retmin; time_t now; - *minor_status = 0; - ctx = (struct gssntlm_ctx *)context_handle; - if (!ctx) return GSS_S_NO_CONTEXT; + if (!ctx) { + return GSSERRS(0, 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 (retmaj) goto done; } if (targ_name) { retmaj = gssntlm_duplicate_name(&retmin, (gss_name_t)&ctx->target_name, targ_name); - if (retmaj) return retmaj; + if (retmaj) goto done; } if (mech_type) { @@ -1097,7 +1080,10 @@ uint32_t gssntlm_inquire_context(uint32_t *minor_status, } } - return GSS_S_COMPLETE; + set_GSSERRS(0, GSS_S_COMPLETE); + +done: + return GSSERR(); } gss_OID_desc set_seq_num_oid = { @@ -1111,42 +1097,42 @@ uint32_t gssntlm_set_sec_context_option(uint32_t *minor_status, const gss_buffer_t value) { struct gssntlm_ctx *ctx; + uint32_t retmin; + uint32_t retmaj; - if (minor_status == NULL) { - return GSS_S_CALL_INACCESSIBLE_WRITE; - } if (context_handle == NULL || *context_handle == NULL) { - return GSS_S_CALL_INACCESSIBLE_READ; + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_READ); } if (desired_object == GSS_C_NO_OID) { - return GSS_S_CALL_INACCESSIBLE_READ; + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_READ); } ctx = (struct gssntlm_ctx *)*context_handle; - *minor_status = 0; - /* set seq num */ if (gss_oid_equal(desired_object, &set_seq_num_oid)) { if (ctx->gss_flags & GSS_C_DATAGRAM_FLAG) { if (value->length != 4) { - *minor_status = EINVAL; - return GSS_S_FAILURE; + set_GSSERR(EINVAL); + goto done; } memcpy(&ctx->crypto_state.recv.seq_num, value->value, value->length); ctx->crypto_state.send.seq_num = ctx->crypto_state.recv.seq_num; - return GSS_S_COMPLETE; + set_GSSERRS(0, GSS_S_COMPLETE); + goto done; } else { - *minor_status = EACCES; - return GSS_S_UNAUTHORIZED; + set_GSSERRS(EACCES, GSS_S_UNAUTHORIZED); + goto done; } } - *minor_status = EINVAL; - return GSS_S_UNAVAILABLE; + set_GSSERRS(EINVAL, GSS_S_UNAVAILABLE); + +done: + return GSSERR(); } gss_OID_desc spnego_req_mic_oid = { @@ -1161,25 +1147,20 @@ uint32_t gssntlm_inquire_sec_context_by_oid(uint32_t *minor_status, { struct gssntlm_ctx *ctx; gss_buffer_desc mic_buf; - uint32_t maj, min; + uint32_t retmaj, retmin, tmpmin; uint8_t mic_set; - if (minor_status == NULL) { - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - - *minor_status = 0; - if (context_handle == NULL) { - return GSS_S_CALL_INACCESSIBLE_READ; + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_READ); } - - ctx = (struct gssntlm_ctx *)context_handle; - if (desired_object == GSS_C_NO_OID) { - return GSS_S_CALL_INACCESSIBLE_READ; + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_READ); + } + if (!data_set) { + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_WRITE); } + ctx = (struct gssntlm_ctx *)context_handle; *data_set = GSS_C_NO_BUFFER_SET; /* the simple fact the spnego layer is asking means it can handle @@ -1199,12 +1180,10 @@ uint32_t gssntlm_inquire_sec_context_by_oid(uint32_t *minor_status, mic_buf.value = &mic_set; mic_buf.length = sizeof(mic_set); - maj = gss_add_buffer_set_member(&min, &mic_buf, data_set); - if (maj != GSS_S_COMPLETE) { - *minor_status = min; - (void)gss_release_buffer_set(&min, data_set); - return maj; + retmaj = gss_add_buffer_set_member(&retmin, &mic_buf, data_set); + if (retmaj != GSS_S_COMPLETE) { + (void)gss_release_buffer_set(&tmpmin, data_set); } - return GSS_S_COMPLETE; + return GSSERRS(retmin, retmaj); } diff --git a/src/gss_serialize.c b/src/gss_serialize.c index aa5da3c..5ea47fe 100644 --- a/src/gss_serialize.c +++ b/src/gss_serialize.c @@ -245,34 +245,34 @@ uint32_t gssntlm_export_sec_context(uint32_t *minor_status, gss_buffer_t interprocess_token) { struct gssntlm_ctx *ctx; - struct export_state state; + struct export_state state = { NULL, 0, 0, 0, 0}; struct export_ctx *ectx; uint64_t expiration; + uint32_t retmaj; + uint32_t retmin; int ret; if (context_handle == NULL) { - return GSS_S_CALL_INACCESSIBLE_READ; + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_READ); } if (interprocess_token == NULL) { - return GSS_S_CALL_INACCESSIBLE_WRITE; + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_WRITE); } ctx = (struct gssntlm_ctx *)*context_handle; - if (ctx == NULL) return GSS_S_NO_CONTEXT; + if (ctx == NULL) return GSSERRS(0, GSS_S_NO_CONTEXT); if (ctx->expiration_time && ctx->expiration_time < time(NULL)) { - return GSS_S_CONTEXT_EXPIRED; + return GSSERRS(0, GSS_S_CONTEXT_EXPIRED); } - *minor_status = 0; - /* serialize context */ state.exp_size = NEW_SIZE(0, sizeof(struct export_ctx)); state.exp_struct = malloc(state.exp_size); if (!state.exp_struct) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; + set_GSSERR(ENOMEM); + goto done; } ectx = (struct export_ctx *)state.exp_struct; state.exp_data = (char *)ectx->data - (char *)ectx; @@ -323,7 +323,10 @@ uint32_t gssntlm_export_sec_context(uint32_t *minor_status, ret = export_data_buffer(&state, ctx->workstation, strlen(ctx->workstation) + 1, &ectx->workstation); - if (ret) goto done; + if (ret) { + set_GSSERR(ret); + goto done; + } } if (ctx->nego_msg.length > 0) { @@ -331,7 +334,10 @@ uint32_t gssntlm_export_sec_context(uint32_t *minor_status, ctx->nego_msg.data, ctx->nego_msg.length, &ectx->nego_msg); - if (ret) goto done; + if (ret) { + set_GSSERR(ret); + goto done; + } } else { ectx->nego_msg.ptr = 0; ectx->nego_msg.len = 0; @@ -342,7 +348,10 @@ uint32_t gssntlm_export_sec_context(uint32_t *minor_status, ctx->chal_msg.data, ctx->chal_msg.length, &ectx->chal_msg); - if (ret) goto done; + if (ret) { + set_GSSERR(ret); + goto done; + } } else { ectx->chal_msg.ptr = 0; ectx->chal_msg.len = 0; @@ -353,17 +362,26 @@ uint32_t gssntlm_export_sec_context(uint32_t *minor_status, ctx->auth_msg.data, ctx->auth_msg.length, &ectx->auth_msg); - if (ret) goto done; + if (ret) { + set_GSSERR(ret); + goto done; + } } else { ectx->auth_msg.ptr = 0; ectx->auth_msg.len = 0; } ret = export_name(&state, &ctx->source_name, &ectx->source); - if (ret) goto done; + if (ret) { + set_GSSERR(ret); + goto done; + } ret = export_name(&state, &ctx->target_name, &ectx->target); - if (ret) goto done; + if (ret) { + set_GSSERR(ret); + goto done; + } memcpy(ectx->server_chal, ctx->server_chal, 8); @@ -374,26 +392,33 @@ uint32_t gssntlm_export_sec_context(uint32_t *minor_status, ctx->exported_session_key.data, ctx->exported_session_key.length, &ectx->exported_session_key); - if (ret) goto done; + if (ret) { + set_GSSERR(ret); + goto done; + } ret = export_keys(&state, &ctx->crypto_state.send, &ectx->send); - if (ret) goto done; + if (ret) { + set_GSSERR(ret); + goto done; + } ret = export_keys(&state, &ctx->crypto_state.recv, &ectx->recv); - if (ret) goto done; + if (ret) { + set_GSSERR(ret); + goto done; + } ectx->int_flags = ctx->int_flags; expiration = ctx->expiration_time; ectx->expration_time = htole64(expiration); - ret = 0; + set_GSSERRS(0, GSS_S_COMPLETE); done: - if (ret) { - *minor_status = ret; + if (retmaj) { free(state.exp_struct); - return GSS_S_FAILURE; } else { uint32_t min; interprocess_token->value = state.exp_struct; @@ -401,9 +426,8 @@ done: /* Invalidate the current context once successfully exported */ gssntlm_delete_sec_context(&min, context_handle, NULL); - - return GSS_S_COMPLETE; } + return GSSERR(); } static uint32_t import_data_buffer(uint32_t *minor_status, @@ -411,10 +435,13 @@ static uint32_t import_data_buffer(uint32_t *minor_status, uint8_t **dest, size_t *len, bool alloc, struct relmem *rm, bool str) { + uint32_t retmaj; + uint32_t retmin; void *ptr; if (rm->ptr + rm->len > state->exp_len) { - return GSS_S_DEFECTIVE_TOKEN; + set_GSSERRS(0, GSS_S_DEFECTIVE_TOKEN); + goto done; } ptr = state->exp_struct + state->exp_data + rm->ptr; if (alloc) { @@ -427,21 +454,25 @@ static uint32_t import_data_buffer(uint32_t *minor_status, } } if (!*dest) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; + set_GSSERR(ENOMEM); + goto done; } } else { if (!*len) { - *minor_status = EINVAL; - return GSS_S_FAILURE; + set_GSSERR(EINVAL); + goto done; } if (rm->len > *len) { - return GSS_S_DEFECTIVE_TOKEN; + set_GSSERRS(0, GSS_S_DEFECTIVE_TOKEN); + goto done; } memcpy(*dest, ptr, rm->len); } if (len) *len = rm->len; - return GSS_S_COMPLETE; + set_GSSERRS(0, GSS_S_COMPLETE); + +done: + return GSSERR(); } static uint32_t import_name(uint32_t *minor_status, @@ -449,56 +480,70 @@ static uint32_t import_name(uint32_t *minor_status, struct export_name *name, struct gssntlm_name *imp_name) { + uint32_t retmaj; + uint32_t retmin; uint8_t *dest; - uint32_t maj; switch (name->type) { case EXP_NAME_NONE: memset(imp_name, 0, sizeof(struct gssntlm_name)); - return GSS_S_COMPLETE; + break; case EXP_NAME_ANON: memset(imp_name, 0, sizeof(struct gssntlm_name)); imp_name->type = GSSNTLM_NAME_ANON; - return GSS_S_COMPLETE; + break; case EXP_NAME_USER: imp_name->type = GSSNTLM_NAME_USER; dest = NULL; if (name->domain.len > 0) { - maj = import_data_buffer(minor_status, state, + retmaj = import_data_buffer(&retmin, state, &dest, NULL, true, &name->domain, true); - if (maj != GSS_S_COMPLETE) return maj; + if (retmaj != GSS_S_COMPLETE) { + set_GSSERRS(retmin, retmaj); + goto done; + } } imp_name->data.user.domain = (char *)dest; dest = NULL; if (name->name.len > 0) { - maj = import_data_buffer(minor_status, state, + retmaj = import_data_buffer(&retmin, state, &dest, NULL, true, &name->name, true); - if (maj != GSS_S_COMPLETE) return maj; + if (retmaj != GSS_S_COMPLETE) { + set_GSSERRS(retmin, retmaj); + goto done; + } } imp_name->data.user.name = (char *)dest; - return GSS_S_COMPLETE; + break; case EXP_NAME_SERV: imp_name->type = GSSNTLM_NAME_SERVER; dest = NULL; if (name->name.len > 0) { - maj = import_data_buffer(minor_status, state, + retmaj = import_data_buffer(&retmin, state, &dest, NULL, true, &name->name, true); - if (maj != GSS_S_COMPLETE) return maj; + if (retmaj != GSS_S_COMPLETE) { + set_GSSERRS(retmin, retmaj); + goto done; + } } imp_name->data.server.name = (char *)dest; - return GSS_S_COMPLETE; + break; default: + set_GSSERRS(0, GSS_S_DEFECTIVE_TOKEN); break; } - return GSS_S_DEFECTIVE_TOKEN; + set_GSSERRS(0, GSS_S_COMPLETE); + +done: + return GSSERR(); } static uint32_t import_keys(uint32_t *minor_status, @@ -508,16 +553,17 @@ static uint32_t import_keys(uint32_t *minor_status, { struct ntlm_buffer in; uint8_t *dest; - uint32_t maj; + uint32_t retmaj; + uint32_t retmin; int ret; if (keys->sign_key.len > 0) { imp_keys->sign_key.length = 16; /* buf max size */ dest = imp_keys->sign_key.data; - maj = import_data_buffer(minor_status, state, + retmaj = import_data_buffer(&retmin, state, &dest, &imp_keys->sign_key.length, false, &keys->sign_key, false); - if (maj != GSS_S_COMPLETE) return maj; + if (retmaj != GSS_S_COMPLETE) goto done; } else { memset(&imp_keys->sign_key, 0, sizeof(struct ntlm_key)); } @@ -525,25 +571,25 @@ static uint32_t import_keys(uint32_t *minor_status, if (keys->seal_key.len > 0) { imp_keys->seal_key.length = 16; /* buf max size */ dest = imp_keys->seal_key.data; - maj = import_data_buffer(minor_status, state, + retmaj = import_data_buffer(&retmin, state, &dest, &imp_keys->seal_key.length, false, &keys->seal_key, false); - if (maj != GSS_S_COMPLETE) return maj; + if (retmaj != GSS_S_COMPLETE) goto done; } else { memset(&imp_keys->seal_key, 0, sizeof(struct ntlm_key)); } if (keys->rc4_state.len > 0) { - maj = import_data_buffer(minor_status, state, + retmaj = import_data_buffer(&retmin, state, &in.data, &in.length, true, &keys->rc4_state, false); - if (maj != GSS_S_COMPLETE) return maj; + if (retmaj != GSS_S_COMPLETE) goto done; ret = RC4_IMPORT(&imp_keys->seal_handle, &in); safezero(in.data, in.length); safefree(in.data); if (ret) { - *minor_status = ret; - return GSS_S_FAILURE; + set_GSSERR(ret); + goto done; } } else { imp_keys->seal_handle = NULL; @@ -551,46 +597,45 @@ static uint32_t import_keys(uint32_t *minor_status, imp_keys->seq_num = le32toh(keys->seq_num); - return GSS_S_COMPLETE; + set_GSSERRS(0, GSS_S_COMPLETE); + +done: + return GSSERR(); } uint32_t gssntlm_import_sec_context(uint32_t *minor_status, gss_buffer_t interprocess_token, gss_ctx_id_t *context_handle) { - struct gssntlm_ctx *ctx; + struct gssntlm_ctx *ctx = NULL; struct export_state state; struct export_ctx *ectx; uint8_t *dest; uint64_t time; - uint32_t maj; - - if (minor_status == NULL) { - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - *minor_status = 0; + uint32_t retmaj; + uint32_t retmin; if (interprocess_token == NULL) { - return GSS_S_CALL_INACCESSIBLE_READ; + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_READ); } if (interprocess_token->length < sizeof(struct export_ctx)) { - return GSS_S_DEFECTIVE_TOKEN; + return GSSERRS(0, GSS_S_DEFECTIVE_TOKEN); } if (context_handle == NULL) { - return GSS_S_CALL_INACCESSIBLE_WRITE; + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_WRITE); } ctx = calloc(1, sizeof(struct gssntlm_ctx)); if (!ctx) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; + set_GSSERR(ENOMEM); + goto done; } - *minor_status = ntlm_init_ctx(&ctx->ntlm); - if (*minor_status) { - free(ctx); - return GSS_S_FAILURE; + retmin = ntlm_init_ctx(&ctx->ntlm); + if (retmin) { + set_GSSERR(retmin); + goto done; } state.exp_struct = interprocess_token->value; @@ -600,7 +645,7 @@ uint32_t gssntlm_import_sec_context(uint32_t *minor_status, state.exp_ptr = 0; if (ectx->version != le16toh(EXPORT_CTX_VER)) { - maj = GSS_S_DEFECTIVE_TOKEN; + set_GSSERRS(0, GSS_S_DEFECTIVE_TOKEN); goto done; } @@ -618,7 +663,7 @@ uint32_t gssntlm_import_sec_context(uint32_t *minor_status, ctx->role = GSSNTLM_DOMAIN_CONTROLLER; break; default: - maj = GSS_S_DEFECTIVE_TOKEN; + set_GSSERRS(0, GSS_S_DEFECTIVE_TOKEN); goto done; } @@ -639,7 +684,7 @@ uint32_t gssntlm_import_sec_context(uint32_t *minor_status, ctx->stage = NTLMSSP_STAGE_DONE; break; default: - maj = GSS_S_DEFECTIVE_TOKEN; + set_GSSERRS(0, GSS_S_DEFECTIVE_TOKEN); goto done; } @@ -647,49 +692,49 @@ uint32_t gssntlm_import_sec_context(uint32_t *minor_status, dest = NULL; if (ectx->workstation.len > 0) { - maj = import_data_buffer(minor_status, &state, &dest, NULL, + retmaj = import_data_buffer(&retmin, &state, &dest, NULL, true, &ectx->workstation, true); - if (maj != GSS_S_COMPLETE) goto done; + if (retmaj != GSS_S_COMPLETE) goto done; } ctx->workstation = (char *)dest; if (ectx->nego_msg.len > 0) { - maj = import_data_buffer(minor_status, &state, + retmaj = import_data_buffer(&retmin, &state, &ctx->nego_msg.data, &ctx->nego_msg.length, true, &ectx->nego_msg, false); - if (maj != GSS_S_COMPLETE) goto done; + if (retmaj != GSS_S_COMPLETE) goto done; } else { ctx->nego_msg.data = NULL; ctx->nego_msg.length = 0; } if (ectx->chal_msg.len > 0) { - maj = import_data_buffer(minor_status, &state, + retmaj = import_data_buffer(&retmin, &state, &ctx->chal_msg.data, &ctx->chal_msg.length, true, &ectx->chal_msg, false); - if (maj != GSS_S_COMPLETE) goto done; + if (retmaj != GSS_S_COMPLETE) goto done; } else { ctx->chal_msg.data = NULL; ctx->chal_msg.length = 0; } if (ectx->auth_msg.len > 0) { - maj = import_data_buffer(minor_status, &state, + retmaj = import_data_buffer(&retmin, &state, &ctx->auth_msg.data, &ctx->auth_msg.length, true, &ectx->auth_msg, false); - if (maj != GSS_S_COMPLETE) goto done; + if (retmaj != GSS_S_COMPLETE) goto done; } else { ctx->auth_msg.data = NULL; ctx->auth_msg.length = 0; } - maj = import_name(minor_status, &state, + retmaj = import_name(&retmin, &state, &ectx->source, &ctx->source_name); - if (maj != GSS_S_COMPLETE) goto done; + if (retmaj != GSS_S_COMPLETE) goto done; - maj = import_name(minor_status, &state, + retmaj = import_name(&retmin, &state, &ectx->target, &ctx->target_name); - if (maj != GSS_S_COMPLETE) goto done; + if (retmaj != GSS_S_COMPLETE) goto done; memcpy(ctx->server_chal, ectx->server_chal, 8); @@ -699,21 +744,21 @@ uint32_t gssntlm_import_sec_context(uint32_t *minor_status, if (ectx->exported_session_key.len > 0) { ctx->exported_session_key.length = 16; /* buf max size */ dest = ctx->exported_session_key.data; - maj = import_data_buffer(minor_status, &state, &dest, + retmaj = import_data_buffer(&retmin, &state, &dest, &ctx->exported_session_key.length, false, &ectx->workstation, true); - if (maj != GSS_S_COMPLETE) goto done; + if (retmaj != GSS_S_COMPLETE) goto done; } else { memset(&ctx->exported_session_key, 0, sizeof(struct ntlm_key)); } - maj = import_keys(minor_status, &state, + retmaj = import_keys(&retmin, &state, &ectx->send, &ctx->crypto_state.send); - if (maj != GSS_S_COMPLETE) goto done; + if (retmaj != GSS_S_COMPLETE) goto done; - maj = import_keys(minor_status, &state, + retmaj = import_keys(&retmin, &state, &ectx->recv, &ctx->crypto_state.recv); - if (maj != GSS_S_COMPLETE) goto done; + if (retmaj != GSS_S_COMPLETE) goto done; /* We need to restoer also the general crypto status flags */ ctx->crypto_state.ext_sec = @@ -726,16 +771,16 @@ uint32_t gssntlm_import_sec_context(uint32_t *minor_status, time = le64toh(ectx->expration_time); ctx->expiration_time = time; - maj = GSS_S_COMPLETE; + set_GSSERRS(0, GSS_S_COMPLETE); done: - if (maj == GSS_S_COMPLETE) { + if (retmaj == GSS_S_COMPLETE) { *context_handle = (gss_ctx_id_t)ctx; } else { uint32_t min; gssntlm_delete_sec_context(&min, (gss_ctx_id_t *)&ctx, NULL); } - return maj; + return GSSERR(); } #pragma pack(push, 1) @@ -762,26 +807,26 @@ uint32_t gssntlm_export_cred(uint32_t *minor_status, gss_buffer_t token) { struct gssntlm_cred *cred; - struct export_state state; + struct export_state state = { NULL, 0, 0, 0, 0 }; struct export_cred *ecred; + uint32_t retmaj; + uint32_t retmin; int ret; - if (token == NULL || minor_status == NULL) { - return GSS_S_CALL_INACCESSIBLE_WRITE; + if (token == NULL) { + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_WRITE); } - *minor_status = 0; - cred = (struct gssntlm_cred *)cred_handle; if (cred_handle == NULL) { - return GSS_S_NO_CRED; + return GSSERRS(0, GSS_S_NO_CRED); } state.exp_size = NEW_SIZE(0, sizeof(struct export_cred)); state.exp_struct = calloc(1, state.exp_size); if (!state.exp_struct) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; + set_GSSERR(ENOMEM); + goto done; } ecred = (struct export_cred *)state.exp_struct; state.exp_data = (char *)ecred->data - (char *)ecred; @@ -801,46 +846,59 @@ uint32_t gssntlm_export_cred(uint32_t *minor_status, ecred->type = EXP_CRED_USER; ret = export_name(&state, &cred->cred.user.user, &ecred->name); - if (ret) goto done; + if (ret) { + set_GSSERR(ret); + goto done; + } ret = export_data_buffer(&state, cred->cred.user.nt_hash.data, cred->cred.user.nt_hash.length, &ecred->nt_hash); - if (ret) goto done; + if (ret) { + set_GSSERR(ret); + goto done; + } ret = export_data_buffer(&state, cred->cred.user.lm_hash.data, cred->cred.user.lm_hash.length, &ecred->lm_hash); - if (ret) goto done; + if (ret) { + set_GSSERR(ret); + goto done; + } break; case GSSNTLM_CRED_SERVER: ecred->type = EXP_CRED_SERVER; ret = export_name(&state, &cred->cred.server.name, &ecred->name); - if (ret) goto done; + if (ret) { + set_GSSERR(ret); + goto done; + } break; case GSSNTLM_CRED_EXTERNAL: ecred->type = EXP_CRED_EXTERNAL; ret = export_name(&state, &cred->cred.external.user, &ecred->name); - if (ret) goto done; + if (ret) { + set_GSSERR(ret); + goto done; + } break; } - ret = 0; + set_GSSERRS(0, GSS_S_COMPLETE); done: - if (ret) { - *minor_status = ret; + if (retmaj) { free(state.exp_struct); - return GSS_S_FAILURE; } else { token->value = state.exp_struct; token->length = state.exp_len; - return GSS_S_COMPLETE; } + return GSSERR(); } uint32_t gssntlm_import_cred(uint32_t *minor_status, @@ -848,31 +906,27 @@ uint32_t gssntlm_import_cred(uint32_t *minor_status, gss_cred_id_t *cred_handle) { struct gssntlm_cred *cred; - struct export_state state; + struct export_state state = { NULL, 0, 0, 0, 0 }; struct export_cred *ecred; - uint32_t maj; - - if (minor_status == NULL) { - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - *minor_status = 0; + uint32_t retmaj; + uint32_t retmin; if (token == NULL) { - return GSS_S_CALL_INACCESSIBLE_READ; + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_READ); } if (token->length < sizeof(struct export_cred)) { - return GSS_S_DEFECTIVE_TOKEN; + return GSSERRS(0, GSS_S_DEFECTIVE_TOKEN); } if (cred_handle == NULL) { - return GSS_S_CALL_INACCESSIBLE_WRITE; + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_WRITE); } cred = calloc(1, sizeof(struct gssntlm_cred)); if (!cred) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; + set_GSSERR(ENOMEM); + goto done; } state.exp_struct = token->value; @@ -882,7 +936,7 @@ uint32_t gssntlm_import_cred(uint32_t *minor_status, state.exp_ptr = 0; if (ecred->version != le16toh(1)) { - maj = GSS_S_DEFECTIVE_TOKEN; + set_GSSERRS(0, GSS_S_DEFECTIVE_TOKEN); goto done; } @@ -895,52 +949,52 @@ uint32_t gssntlm_import_cred(uint32_t *minor_status, break; case EXP_CRED_USER: cred->type = GSSNTLM_CRED_USER; - maj = import_name(minor_status, &state, &ecred->name, + retmaj = import_name(&retmin, &state, &ecred->name, &cred->cred.user.user); - if (maj != GSS_S_COMPLETE) goto done; + if (retmaj != GSS_S_COMPLETE) goto done; if (ecred->nt_hash.len > 16 || ecred->lm_hash.len > 16) { - maj = GSS_S_DEFECTIVE_TOKEN; + set_GSSERRS(0, GSS_S_DEFECTIVE_TOKEN); goto done; } - maj = import_data_buffer(minor_status, &state, + retmaj = import_data_buffer(&retmin, &state, (uint8_t **)&cred->cred.user.nt_hash.data, &cred->cred.user.nt_hash.length, false, &ecred->nt_hash, false); - if (maj != GSS_S_COMPLETE) goto done; + if (retmaj != GSS_S_COMPLETE) goto done; - maj = import_data_buffer(minor_status, &state, + retmaj = import_data_buffer(&retmin, &state, (uint8_t **)&cred->cred.user.lm_hash.data, &cred->cred.user.lm_hash.length, false, &ecred->lm_hash, false); - if (maj != GSS_S_COMPLETE) goto done; + if (retmaj != GSS_S_COMPLETE) goto done; break; case EXP_CRED_SERVER: cred->type = GSSNTLM_CRED_SERVER; - maj = import_name(minor_status, &state, &ecred->name, + retmaj = import_name(&retmin, &state, &ecred->name, &cred->cred.server.name); - if (maj != GSS_S_COMPLETE) goto done; + if (retmaj != GSS_S_COMPLETE) goto done; break; case EXP_CRED_EXTERNAL: cred->type = GSSNTLM_CRED_EXTERNAL; - maj = import_name(minor_status, &state, &ecred->name, + retmaj = import_name(&retmin, &state, &ecred->name, &cred->cred.external.user); - if (maj != GSS_S_COMPLETE) goto done; + if (retmaj != GSS_S_COMPLETE) goto done; break; default: - maj = GSS_S_DEFECTIVE_TOKEN; + set_GSSERRS(0, GSS_S_DEFECTIVE_TOKEN); break; } - maj = GSS_S_COMPLETE; + set_GSSERRS(0, GSS_S_COMPLETE); done: - if (maj == GSS_S_COMPLETE) { + if (retmaj == GSS_S_COMPLETE) { *cred_handle = (gss_cred_id_t)cred; } else { uint32_t min; gssntlm_release_cred(&min, (gss_cred_id_t *)&cred); } - return maj; + return GSSERR(); } diff --git a/src/gss_signseal.c b/src/gss_signseal.c index aaf8218..b74fe28 100644 --- a/src/gss_signseal.c +++ b/src/gss_signseal.c @@ -34,24 +34,21 @@ uint32_t gssntlm_get_mic(uint32_t *minor_status, struct ntlm_buffer signature; uint32_t retmaj, retmin; - *minor_status = 0; - ctx = (struct gssntlm_ctx *)context_handle; retmaj = gssntlm_context_is_valid(ctx, NULL); if (retmaj != GSS_S_COMPLETE) { - return retmaj; + return GSSERRS(0, retmaj); } if (qop_req != GSS_C_QOP_DEFAULT) { - return GSS_S_BAD_QOP; + return GSSERRS(0, GSS_S_BAD_QOP); } if (!message_buffer->value || message_buffer->length == 0) { - return GSS_S_CALL_INACCESSIBLE_READ; + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_READ); } message_token->value = malloc(NTLM_SIGNATURE_SIZE); if (!message_token->value) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; + return GSSERRS(ENOMEM, GSS_S_FAILURE); } message_token->length = NTLM_SIGNATURE_SIZE; @@ -63,12 +60,11 @@ uint32_t gssntlm_get_mic(uint32_t *minor_status, &ctx->crypto_state, &message, &signature); if (retmin) { - *minor_status = retmin; safefree(message_token->value); - return GSS_S_FAILURE; + return GSSERRS(retmin, GSS_S_FAILURE); } - return GSS_S_COMPLETE; + return GSSERRS(0, GSS_S_COMPLETE); } uint32_t gssntlm_verify_mic(uint32_t *minor_status, @@ -83,15 +79,13 @@ uint32_t gssntlm_verify_mic(uint32_t *minor_status, struct ntlm_buffer signature = { token, NTLM_SIGNATURE_SIZE }; uint32_t retmaj, retmin; - *minor_status = 0; - ctx = (struct gssntlm_ctx *)context_handle; retmaj = gssntlm_context_is_valid(ctx, NULL); if (retmaj != GSS_S_COMPLETE) { - return retmaj; + return GSSERRS(0, retmaj); } if (!message_buffer->value || message_buffer->length == 0) { - return GSS_S_CALL_INACCESSIBLE_READ; + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_READ); } if (qop_state) { *qop_state = GSS_C_QOP_DEFAULT; @@ -103,16 +97,15 @@ uint32_t gssntlm_verify_mic(uint32_t *minor_status, &ctx->crypto_state, &message, &signature); if (retmin) { - *minor_status = retmin; - return GSS_S_FAILURE; + return GSSERRS(retmin, GSS_S_FAILURE); } if (memcmp(signature.data, message_token->value, NTLM_SIGNATURE_SIZE) != 0) { - return GSS_S_BAD_SIG; + return GSSERRS(0, GSS_S_BAD_SIG); } - return GSS_S_COMPLETE; + return GSSERRS(0, GSS_S_COMPLETE); } uint32_t gssntlm_wrap(uint32_t *minor_status, @@ -129,18 +122,16 @@ uint32_t gssntlm_wrap(uint32_t *minor_status, struct ntlm_buffer signature; uint32_t retmaj, retmin; - *minor_status = 0; - ctx = (struct gssntlm_ctx *)context_handle; retmaj = gssntlm_context_is_valid(ctx, NULL); if (retmaj != GSS_S_COMPLETE) { - return retmaj; + return GSSERRS(0, retmaj); } if (qop_req != GSS_C_QOP_DEFAULT) { - return GSS_S_BAD_QOP; + return GSSERRS(0, GSS_S_BAD_QOP); } if (!input_message_buffer->value || input_message_buffer->length == 0) { - return GSS_S_CALL_INACCESSIBLE_READ; + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_READ); } if (conf_state) { *conf_state = 0; @@ -154,8 +145,7 @@ uint32_t gssntlm_wrap(uint32_t *minor_status, input_message_buffer->length + NTLM_SIGNATURE_SIZE; output_message_buffer->value = malloc(output_message_buffer->length); if (!output_message_buffer->value) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; + return GSSERRS(ENOMEM, GSS_S_FAILURE); } message.data = input_message_buffer->value; @@ -167,12 +157,11 @@ uint32_t gssntlm_wrap(uint32_t *minor_status, retmin = ntlm_seal(ctx->neg_flags, &ctx->crypto_state, &message, &output, &signature); if (retmin) { - *minor_status = retmin; safefree(output_message_buffer->value); - return GSS_S_FAILURE; + return GSSERRS(retmin, GSS_S_FAILURE); } - return GSS_S_COMPLETE; + return GSSERRS(0, GSS_S_COMPLETE); } uint32_t gssntlm_unwrap(uint32_t *minor_status, @@ -189,15 +178,13 @@ uint32_t gssntlm_unwrap(uint32_t *minor_status, struct ntlm_buffer signature = { sig, NTLM_SIGNATURE_SIZE }; uint32_t retmaj, retmin; - *minor_status = 0; - ctx = (struct gssntlm_ctx *)context_handle; retmaj = gssntlm_context_is_valid(ctx, NULL); if (retmaj != GSS_S_COMPLETE) { - return retmaj; + return GSSERRS(0, retmaj); } if (!input_message_buffer->value || input_message_buffer->length == 0) { - return GSS_S_CALL_INACCESSIBLE_READ; + return GSSERRS(0, GSS_S_CALL_INACCESSIBLE_READ); } if (conf_state) { *conf_state = 0; @@ -210,8 +197,7 @@ uint32_t gssntlm_unwrap(uint32_t *minor_status, input_message_buffer->length - NTLM_SIGNATURE_SIZE; output_message_buffer->value = malloc(output_message_buffer->length); if (!output_message_buffer->value) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; + return GSSERRS(ENOMEM, GSS_S_FAILURE); } message.data = (uint8_t *)input_message_buffer->value + NTLM_SIGNATURE_SIZE; @@ -221,18 +207,17 @@ uint32_t gssntlm_unwrap(uint32_t *minor_status, retmin = ntlm_unseal(ctx->neg_flags, &ctx->crypto_state, &message, &output, &signature); if (retmin) { - *minor_status = retmin; safefree(output_message_buffer->value); - return GSS_S_FAILURE; + return GSSERRS(0, GSS_S_FAILURE); } if (memcmp(input_message_buffer->value, signature.data, NTLM_SIGNATURE_SIZE) != 0) { safefree(output_message_buffer->value); - return GSS_S_BAD_SIG; + return GSSERRS(0, GSS_S_BAD_SIG); } - return GSS_S_COMPLETE; + return GSSERRS(0, GSS_S_COMPLETE); } uint32_t gssntlm_wrap_size_limit(uint32_t *minor_status, @@ -243,18 +228,16 @@ uint32_t gssntlm_wrap_size_limit(uint32_t *minor_status, uint32_t *max_input_size) { struct gssntlm_ctx *ctx; - uint32_t retmaj; - - *minor_status = 0; + uint32_t retmaj, retmin; ctx = (struct gssntlm_ctx *)context_handle; retmaj = gssntlm_context_is_valid(ctx, NULL); if (retmaj != GSS_S_COMPLETE) { - return retmaj; + return GSSERRS(0, retmaj); } if (qop_req != GSS_C_QOP_DEFAULT) { - return GSS_S_BAD_QOP; + return GSSERRS(0, GSS_S_BAD_QOP); } if (req_output_size < 16) { @@ -263,5 +246,5 @@ uint32_t gssntlm_wrap_size_limit(uint32_t *minor_status, *max_input_size = req_output_size - NTLM_SIGNATURE_SIZE; } - return GSS_S_COMPLETE; + return GSSERRS(0, GSS_S_COMPLETE); } |