summaryrefslogtreecommitdiffstats
path: root/src/gss_ntlmssp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gss_ntlmssp.c')
-rw-r--r--src/gss_ntlmssp.c137
1 files changed, 136 insertions, 1 deletions
diff --git a/src/gss_ntlmssp.c b/src/gss_ntlmssp.c
index 7762b23..d9ebe80 100644
--- a/src/gss_ntlmssp.c
+++ b/src/gss_ntlmssp.c
@@ -15,11 +15,146 @@
License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gssapi/gssapi.h>
+#include <gssapi/gssapi_ext.h>
+
#include "gss_ntlmssp.h"
/* 1.3.6.1.4.1.311.2.2.10 */
-const gss_OID_desc gss_ntlm_oid = {
+const gss_OID_desc gssntlm_oid = {
.length = 10,
.elements = "\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a"
};
+uint8_t gssntlm_required_security(int security_level,
+ enum gssntlm_role role)
+{
+ uint8_t resp;
+
+ /* DC defaults */
+ resp = SEC_DC_LM_OK | SEC_DC_NTLM_OK | SEC_DC_V2_OK;
+
+ switch (security_level) {
+ case 0:
+ resp |= SEC_LM_OK | SEC_NTLM_OK;
+ break;
+ case 1:
+ resp |= SEC_LM_OK | SEC_NTLM_OK | SEC_EXT_SEC_OK;
+ break;
+ case 2:
+ resp |= SEC_NTLM_OK | SEC_EXT_SEC_OK;
+ break;
+ case 3:
+ resp |= SEC_V2_ONLY | SEC_EXT_SEC_OK;
+ break;
+ case 4:
+ resp |= SEC_NTLM_OK | SEC_EXT_SEC_OK;
+ if (role == GSSNTLM_DOMAIN_CONTROLLER) resp &= ~SEC_DC_LM_OK;
+ break;
+ case 5:
+ if (role == GSSNTLM_DOMAIN_CONTROLLER) resp = SEC_DC_V2_OK;
+ resp |= SEC_V2_ONLY | SEC_EXT_SEC_OK;
+ break;
+ default:
+ resp = 0xff;
+ break;
+ }
+
+ return resp;
+}
+
+int gssntlm_copy_creds(struct gssntlm_cred *in, struct gssntlm_cred *out)
+{
+ char *dom = NULL, *usr = NULL;
+ int ret = 0;
+
+ out->type = GSSNTLM_CRED_NONE;
+
+ switch (in->type) {
+ case GSSNTLM_CRED_NONE:
+ break;
+ case GSSNTLM_CRED_ANON:
+ out->cred.anon.dummy = 1;
+ break;
+ case GSSNTLM_CRED_USER:
+ dom = strdup(in->cred.user.user.data.user.domain);
+ if (!dom) {
+ ret = ENOMEM;
+ goto done;
+ }
+ usr = strdup(in->cred.user.user.data.user.name);
+ if (!usr) {
+ ret = ENOMEM;
+ goto done;
+ }
+ out->cred.user.user.data.user.domain = dom;
+ out->cred.user.user.data.user.name = usr;
+ break;
+ case GSSNTLM_CRED_SERVER:
+ out->cred.server.dummy = 1;
+ break;
+ }
+
+ out->type = in->type;
+
+done:
+ if (ret) {
+ safefree(dom);
+ safefree(usr);
+ }
+ return ret;
+}
+
+void gssntlm_int_release_cred(struct gssntlm_cred *cred)
+{
+ switch (cred->type) {
+ case GSSNTLM_CRED_NONE:
+ break;
+ case GSSNTLM_CRED_ANON:
+ cred->cred.anon.dummy = 0;
+ break;
+ case GSSNTLM_CRED_USER:
+ safefree(cred->cred.user.user.data.user.domain);
+ safefree(cred->cred.user.user.data.user.name);
+ safezero(cred->cred.user.nt_hash.data, 16);
+ cred->cred.user.nt_hash.length = 0;
+ safezero(cred->cred.user.lm_hash.data, 16);
+ cred->cred.user.lm_hash.length = 0;
+ break;
+ case GSSNTLM_CRED_SERVER:
+ cred->cred.server.dummy = 0;
+ break;
+ }
+}
+
+uint32_t gssntlm_acquire_cred(uint32_t *minor_status,
+ gss_name_t desired_name,
+ uint32_t time_req,
+ gss_OID_set desired_mechs,
+ gss_cred_usage_t cred_usage,
+ gss_cred_id_t *output_cred_handle,
+ gss_OID_set *actual_mechs,
+ uint32_t *time_rec)
+{
+ /* FIXME: Fecth creds from somewhere */
+ *minor_status = 0;
+ return GSS_S_CRED_UNAVAIL;
+}
+
+uint32_t gssntlm_release_cred(uint32_t *minor_status,
+ gss_cred_id_t *cred_handle)
+{
+ *minor_status = 0;
+
+ if (!cred_handle) return GSS_S_COMPLETE;
+
+ gssntlm_int_release_cred((struct gssntlm_cred *)*cred_handle);
+ safefree(*cred_handle);
+
+ return GSS_S_COMPLETE;
+}
+