Ejemplo n.º 1
0
AUTH *
krb5_use_machine_creds(struct clnt_info *clp, uid_t uid, char *tgtname,
		    char *service, CLIENT **rpc_clnt)
{
	AUTH	*auth = NULL;
	char	**credlist = NULL;
	char	**ccname;
	int	nocache = 0;
	int	success = 0;

	printerr(2, "krb5_use_machine_creds: uid %d tgtname %s\n", 
		uid, tgtname);

	do {
		gssd_refresh_krb5_machine_credential(clp->servername, NULL,
						service);
	/*
	 * Get a list of credential cache names and try each
	 * of them until one works or we've tried them all
	 */
		if (gssd_get_krb5_machine_cred_list(&credlist)) {
			printerr(0, "ERROR: No credentials found "
				"for connection to server %s\n",
				clp->servername);
			goto out;
		}
		for (ccname = credlist; ccname && *ccname; ccname++) {
			gssd_setup_krb5_machine_gss_ccache(*ccname);
			if ((create_auth_rpc_client(clp, tgtname, rpc_clnt,
						&auth, uid,
						AUTHTYPE_KRB5,
						GSS_C_NO_CREDENTIAL)) == 0) {
				/* Success! */
				success++;
				break;
			}
			printerr(2, "WARNING: Failed to create machine krb5"
				"context with cred cache %s for server %s\n",
				*ccname, clp->servername);
		}
		gssd_free_krb5_machine_cred_list(credlist);
		if (!success) {
			if(nocache == 0) {
				nocache++;
				printerr(2, "WARNING: Machine cache prematurely"					 "expired or corrupted trying to"
					 "recreate cache for server %s\n",
					clp->servername);
			} else {
				printerr(1, "WARNING: Failed to create machine"
					 "krb5 context with any credentials"
					 "cache for server %s\n",
					clp->servername);
				goto out;
			}
		}
	} while(!success);

out:
	return auth;
}
Ejemplo n.º 2
0
/*
 * Return an array of pointers to names of credential cache files
 * which can be used to try to create gss contexts with a server.
 *
 * Returns:
 *	0 => list is attached
 *	nonzero => error
 */
int
gssd_get_krb5_machine_cred_list(char ***list)
{
	char **l;
	int listinc = 10;
	int listsize = listinc;
	int i = 0;
	int retval;
	struct gssd_k5_kt_princ *ple;

	/* Assume failure */
	retval = -1;
	*list = (char **) NULL;

	if ((l = (char **) malloc(listsize * sizeof(char *))) == NULL) {
		retval = ENOMEM;
		goto out;
	}

	/* Need to serialize list if we ever become multi-threaded! */

	for (ple = gssd_k5_kt_princ_list; ple; ple = ple->next) {
		if (ple->ccname) {
			/* Make sure cred is up-to-date before returning it */
			retval = gssd_refresh_krb5_machine_credential(NULL, ple);
			if (retval)
				continue;
			if (i + 1 > listsize) {
				listsize += listinc;
				l = (char **)
					realloc(l, listsize * sizeof(char *));
				if (l == NULL) {
					retval = ENOMEM;
					goto out;
				}
			}
			if ((l[i++] = strdup(ple->ccname)) == NULL) {
				retval = ENOMEM;
				goto out;
			}
		}
	}
	if (i > 0) {
		l[i] = NULL;
		*list = l;
		retval = 0;
		goto out;
	}
  out:
	return retval;
}
Ejemplo n.º 3
0
static inline void
nfs_rpc_callback_setup_gss(rpc_call_channel_t *chan,
                           nfs_client_cred_t *cred)
{
    AUTH *auth;
    char hprinc[MAXPATHLEN];
    int32_t code = 0;

    assert(cred->flavor == RPCSEC_GSS);

    /* MUST RFC 3530bis, section 3.3.3 */
    chan->gss_sec.svc = cred->auth_union.auth_gss.svc;
    chan->gss_sec.qop = cred->auth_union.auth_gss.qop;

    /* the GSSAPI k5 mech needs to find an unexpired credential
     * for nfs/hostname in an accessible k5ccache */
    code = gssd_refresh_krb5_machine_credential(
        host_name, NULL, nfs_param.krb5_param.svc.principal);
    if (code) {
        LogWarn(COMPONENT_NFS_CB, "gssd_refresh_krb5_machine_credential "
                 "failed (%d:%d)", code, errno);
        goto out;
    }

    if (! format_host_principal(chan, hprinc, sizeof(hprinc))) {
        LogCrit(COMPONENT_NFS_CB, "format_host_principal failed");
        goto out;
    }

    chan->gss_sec.cred = GSS_C_NO_CREDENTIAL;
    chan->gss_sec.req_flags = 0;

    if (chan->gss_sec.svc != RPCSEC_GSS_SVC_NONE) {
        /* no more lipkey, spkm3 */
        chan->gss_sec.mech = (gss_OID) &krb5oid;
        chan->gss_sec.req_flags = GSS_C_MUTUAL_FLAG; /* XXX */
        auth = 
            authgss_create_default(chan->clnt,
                                   hprinc,
                                   &chan->gss_sec);
        /* authgss_create and authgss_create_default return NULL on
         * failure, don't assign NULL to clnt->cl_auth */
        if (auth)
            chan->auth = auth;
    }

out:
    return;
}
Ejemplo n.º 4
0
static inline void
nfs_rpc_cb_init_ccache(const char *ccache)
{
    int code = 0;

    mkdir(ccache, 700); /* XXX */
    ccachesearch[0] = nfs_param.krb5_param.ccache_dir;

    code = gssd_refresh_krb5_machine_credential(
        host_name, NULL, nfs_param.krb5_param.svc.principal);
    if (code) {
        LogWarn(COMPONENT_INIT, "gssd_refresh_krb5_machine_credential "
                 "failed (%d:%d)", code, errno);
        goto out;
    }

out:
    return;
}