turn down some warnings
[openssh.git] / gss-serv.c
index 0680ac8..2a6bfbf 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenBSD: gss-serv.c,v 1.22 2008/05/08 12:02:23 djm Exp $ */
 
 /*
- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "channels.h"
 #include "session.h"
 #include "misc.h"
+#include "servconf.h"
+#include "uidswap.h"
 
 #include "ssh-gss.h"
+#include "monitor_wrap.h"
+
+extern ServerOptions options;
 
 static ssh_gssapi_client gssapi_client =
     { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER,
@@ -66,25 +71,32 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx)
        char lname[MAXHOSTNAMELEN];
        gss_OID_set oidset;
 
-       gss_create_empty_oid_set(&status, &oidset);
-       gss_add_oid_set_member(&status, ctx->oid, &oidset);
+       if (options.gss_strict_acceptor) {
+               gss_create_empty_oid_set(&status, &oidset);
+               gss_add_oid_set_member(&status, ctx->oid, &oidset);
 
-       if (gethostname(lname, MAXHOSTNAMELEN)) {
-               gss_release_oid_set(&status, &oidset);
-               return (-1);
-       }
+               if (gethostname(lname, MAXHOSTNAMELEN)) {
+                       gss_release_oid_set(&status, &oidset);
+                       return (-1);
+               }
+
+               if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) {
+                       gss_release_oid_set(&status, &oidset);
+                       return (ctx->major);
+               }
+
+               if ((ctx->major = gss_acquire_cred(&ctx->minor,
+                   ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, 
+                   NULL, NULL)))
+                       ssh_gssapi_error(ctx);
 
-       if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) {
                gss_release_oid_set(&status, &oidset);
                return (ctx->major);
+       } else {
+               ctx->name = GSS_C_NO_NAME;
+               ctx->creds = GSS_C_NO_CREDENTIAL;
        }
-
-       if ((ctx->major = gss_acquire_cred(&ctx->minor,
-           ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL)))
-               ssh_gssapi_error(ctx);
-
-       gss_release_oid_set(&status, &oidset);
-       return (ctx->major);
+       return GSS_S_COMPLETE;
 }
 
 /* Privileged */
@@ -99,6 +111,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid)
 }
 
 /* Unprivileged */
+char *
+ssh_gssapi_server_mechanisms() {
+       gss_OID_set     supported;
+
+       ssh_gssapi_supported_oids(&supported);
+       return (ssh_gssapi_kex_mechs(supported, &ssh_gssapi_server_check_mech,
+           NULL, NULL));
+}
+
+/* Unprivileged */
+int
+ssh_gssapi_server_check_mech(Gssctxt **dum, gss_OID oid, const char *data,
+    const char *dummy) {
+       Gssctxt *ctx = NULL;
+       int res;
+       res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid)));
+       ssh_gssapi_delete_ctx(&ctx);
+
+       return (res);
+}
+
+/* Unprivileged */
 void
 ssh_gssapi_supported_oids(gss_OID_set *oidset)
 {
@@ -131,7 +166,7 @@ ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *recv_tok,
 
        if (ctx->client_creds)
                debug("Received some client credentials");
-       else
+       else if (ctx->major == GSS_S_COMPLETE)
                debug("Got no client credentials");
 
        status = ctx->major;
@@ -240,6 +275,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
                return (ctx->major);
        }
 
+       gss_release_buffer(&ctx->minor, &ename);
+
        /* We can't copy this structure, so we just move the pointer to it */
        client->creds = ctx->client_creds;
        ctx->client_creds = GSS_C_NO_CREDENTIAL;
@@ -288,7 +325,7 @@ ssh_gssapi_do_child(char ***envp, u_int *envsizep)
 
 /* Privileged */
 int
-ssh_gssapi_userok(char *user)
+ssh_gssapi_userok(char *user, struct passwd *pw)
 {
        OM_uint32 lmin;
        int userok = 0;
@@ -298,28 +335,42 @@ ssh_gssapi_userok(char *user)
                debug("No suitable client data");
                return 0;
        }
-       if (GSS_ERROR(gss_userok(&lmin, gssapi_client.name, user, &userok)) ||
-           userok == 0) {
+
+       userok = gss_userok(gssapi_client.name, user);
+       if (userok) {
+               gssapi_client.used = 1;
+               gssapi_client.store.owner = pw;
+       } else {
                /* Destroy delegated credentials if userok fails */
                gss_release_buffer(&lmin, &gssapi_client.displayname);
                gss_release_buffer(&lmin, &gssapi_client.exportedname);
                gss_release_name(&lmin, &gssapi_client.name);
                gss_release_cred(&lmin, &gssapi_client.creds);
                memset(&gssapi_client, 0, sizeof(ssh_gssapi_client));
-               return 0;
        }
 
        return (userok);
 }
 
-/* Privileged */
+/* Priviledged */
 OM_uint32
-ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
+ssh_gssapi_localname(char **user)
 {
-       ctx->major = gss_verify_mic(&ctx->minor, ctx->context,
-           gssbuf, gssmic, NULL);
+       OM_uint32 major_status, lmin;
+       uid_t uid;
+       struct passwd *pw;
 
-       return (ctx->major);
-}
+       major_status = gss_pname_to_uid(&lmin, gssapi_client.name,
+                                       GSS_C_NO_OID, &uid);
+       if (GSS_ERROR(major_status))
+               return (major_status);
 
-#endif
+       pw = getpwuid(uid);
+       if (pw == NULL)
+               return (GSS_S_BAD_NAME);
+
+       *user = xstrdup(pw->pw_name);
+
+       return (GSS_S_COMPLETE);
+}
+#endif /* GSSAPI */