* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
-#include "config.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif /* HAVE_CONFIG_H */
+
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
/* Global gssd_credentials handle */
gss_cred_id_t gssd_creds;
-gss_OID g_mechOid = GSS_C_NULL_OID;;
+gss_OID g_mechOid = GSS_C_NULL_OID;
#if 0
static void
}
}
#endif
+static char *
+gss_display_error(OM_uint32 status)
+{
+ char *error = NULL;
+
+ switch(status) {
+ case GSS_S_COMPLETE:
+ error = "GSS_S_COMPLETE";
+ break;
+ case GSS_S_CALL_INACCESSIBLE_READ:
+ error = "GSS_S_CALL_INACCESSIBLE_READ";
+ break;
+ case GSS_S_CALL_INACCESSIBLE_WRITE:
+ error = "GSS_S_CALL_INACCESSIBLE_WRITE";
+ break;
+ case GSS_S_CALL_BAD_STRUCTURE:
+ error = "GSS_S_CALL_BAD_STRUCTURE";
+ break;
+ case GSS_S_BAD_MECH:
+ error = "GSS_S_BAD_MECH";
+ break;
+ case GSS_S_BAD_NAME:
+ error = "GSS_S_BAD_NAME";
+ break;
+ case GSS_S_BAD_NAMETYPE:
+ error = "GSS_S_BAD_NAMETYPE";
+ break;
+ case GSS_S_BAD_BINDINGS:
+ error = "GSS_S_BAD_BINDINGS";
+ break;
+ case GSS_S_BAD_STATUS:
+ error = "GSS_S_BAD_STATUS";
+ break;
+ case GSS_S_BAD_SIG:
+ error = "GSS_S_BAD_SIG";
+ break;
+ case GSS_S_NO_CRED:
+ error = "GSS_S_NO_CRED";
+ break;
+ case GSS_S_NO_CONTEXT:
+ error = "GSS_S_NO_CONTEXT";
+ break;
+ case GSS_S_DEFECTIVE_TOKEN:
+ error = "GSS_S_DEFECTIVE_TOKEN";
+ break;
+ case GSS_S_DEFECTIVE_CREDENTIAL:
+ error = "GSS_S_DEFECTIVE_CREDENTIAL";
+ break;
+ case GSS_S_CREDENTIALS_EXPIRED:
+ error = "GSS_S_CREDENTIALS_EXPIRED";
+ break;
+ case GSS_S_CONTEXT_EXPIRED:
+ error = "GSS_S_CONTEXT_EXPIRED";
+ break;
+ case GSS_S_FAILURE:
+ error = "GSS_S_FAILURE";
+ break;
+ case GSS_S_BAD_QOP:
+ error = "GSS_S_BAD_QOP";
+ break;
+ case GSS_S_UNAUTHORIZED:
+ error = "GSS_S_UNAUTHORIZED";
+ break;
+ case GSS_S_UNAVAILABLE:
+ error = "GSS_S_UNAVAILABLE";
+ break;
+ case GSS_S_DUPLICATE_ELEMENT:
+ error = "GSS_S_DUPLICATE_ELEMENT";
+ break;
+ case GSS_S_NAME_NOT_MN:
+ error = "GSS_S_NAME_NOT_MN";
+ break;
+ default:
+ error = "Not defined";
+ }
+ return error;
+}
static void
display_status_2(char *m, u_int32_t major, u_int32_t minor, const gss_OID mech)
char maj_buf[30], min_buf[30];
char *maj, *min;
u_int32_t msg_ctx = 0;
+ int msg_verbosity = 0;
/* Get major status message */
maj_stat1 = gss_display_status(&min_stat1, major,
min = min_gss_buf.value;
}
- printerr(0, "ERROR: GSS-API: error in %s(): %s - %s\n",
- m, maj, min);
+ if (major == GSS_S_CREDENTIALS_EXPIRED)
+ msg_verbosity = 1;
+
+ printerr(msg_verbosity, "ERROR: GSS-API: error in %s(): %s (%s) - %s\n",
+ m, gss_display_error(major), maj, min);
if (maj_gss_buf.length != 0)
(void) gss_release_buffer(&min_stat1, &maj_gss_buf);
}
int
-gssd_acquire_cred(char *server_name)
+gssd_acquire_cred(char *server_name, const gss_OID oid)
{
gss_buffer_desc name;
gss_name_t target_name;
u_int32_t maj_stat, min_stat;
u_int32_t ignore_maj_stat, ignore_min_stat;
+ gss_buffer_desc pbuf;
- name.value = (void *)server_name;
- name.length = strlen(server_name);
+ /* If server_name is NULL, get cred for GSS_C_NO_NAME */
+ if (server_name == NULL) {
+ target_name = GSS_C_NO_NAME;
+ } else {
+ name.value = (void *)server_name;
+ name.length = strlen(server_name);
- maj_stat = gss_import_name(&min_stat, &name,
- (const gss_OID) GSS_C_NT_HOSTBASED_SERVICE,
- &target_name);
+ maj_stat = gss_import_name(&min_stat, &name,
+ oid,
+ &target_name);
- if (maj_stat != GSS_S_COMPLETE) {
- pgsserr("gss_import_name", maj_stat, min_stat, g_mechOid);
- return (FALSE);
+ if (maj_stat != GSS_S_COMPLETE) {
+ pgsserr("gss_import_name", maj_stat, min_stat, g_mechOid);
+ return (FALSE);
+ }
}
- maj_stat = gss_acquire_cred(&min_stat, target_name, 0,
- GSS_C_NULL_OID_SET, GSS_C_ACCEPT,
+ maj_stat = gss_acquire_cred(&min_stat, target_name, GSS_C_INDEFINITE,
+ GSS_C_NO_OID_SET, GSS_C_ACCEPT,
&gssd_creds, NULL, NULL);
- ignore_maj_stat = gss_release_name(&ignore_min_stat, &target_name);
-
- if (maj_stat != GSS_S_COMPLETE)
+ if (maj_stat != GSS_S_COMPLETE) {
pgsserr("gss_acquire_cred", maj_stat, min_stat, g_mechOid);
+ ignore_maj_stat = gss_display_name(&ignore_min_stat,
+ target_name, &pbuf, NULL);
+ if (ignore_maj_stat == GSS_S_COMPLETE) {
+ printerr(1, "Unable to obtain credentials for '%.*s'\n",
+ pbuf.length, pbuf.value);
+ ignore_maj_stat = gss_release_buffer(&ignore_min_stat,
+ &pbuf);
+ }
+ }
+
+ ignore_maj_stat = gss_release_name(&ignore_min_stat, &target_name);
return (maj_stat == GSS_S_COMPLETE);
}
+
+int gssd_check_mechs(void)
+{
+ u_int32_t maj_stat, min_stat;
+ gss_OID_set supported_mechs = GSS_C_NO_OID_SET;
+ int retval = -1;
+
+ maj_stat = gss_indicate_mechs(&min_stat, &supported_mechs);
+ if (maj_stat != GSS_S_COMPLETE) {
+ printerr(0, "Unable to obtain list of supported mechanisms. "
+ "Check that gss library is properly configured.\n");
+ goto out;
+ }
+ if (supported_mechs == GSS_C_NO_OID_SET ||
+ supported_mechs->count == 0) {
+ printerr(0, "Unable to obtain list of supported mechanisms. "
+ "Check that gss library is properly configured.\n");
+ goto out;
+ }
+ maj_stat = gss_release_oid_set(&min_stat, &supported_mechs);
+ retval = 0;
+out:
+ return retval;
+}
+