Ejemplo n.º 1
0
static E2kKerberosResult
get_init_cred (krb5_context ctx, const char *usr_name, const char *passwd,
	       const char *in_tkt_service, krb5_creds *cred)
{
	krb5_principal principal;
	krb5_get_init_creds_opt opt;
	krb5_error_code result;

	result = krb5_parse_name (ctx, usr_name, &principal);
	if (result)
		return E2K_KERBEROS_USER_UNKNOWN;

	krb5_get_init_creds_opt_init (&opt);
	krb5_get_init_creds_opt_set_tkt_life (&opt, 5*60);
	krb5_get_init_creds_opt_set_renew_life (&opt, 0);
	krb5_get_init_creds_opt_set_forwardable (&opt, 0);
	krb5_get_init_creds_opt_set_proxiable (&opt, 0);

	result = krb5_get_init_creds_password (ctx, cred, principal,
					       (char *) passwd,
					       NULL, NULL, 0,
					       (char *) in_tkt_service, &opt);
	krb5_free_principal (ctx, principal);

	return krb5_result_to_e2k_kerberos_result (result);
}
Ejemplo n.º 2
0
void ceo_krb5_auth(char *principal) {
    krb5_error_code retval;
    krb5_creds creds;
    krb5_principal princ;
    krb5_ccache cache;
    krb5_get_init_creds_opt options;

    krb5_get_init_creds_opt_init(&options);
    memset(&creds, 0, sizeof(creds));

    debug("krb5: getting TGT using keytab for %s", principal);

    if ((retval = krb5_parse_name(context, principal, &princ)))
        com_err(prog, retval, "while resolving user %s", principal);

    if ((retval = krb5_cc_default(context, &cache)))
        com_err(prog, retval, "while resolving credentials cache");

    if ((retval = krb5_get_init_creds_keytab(context, &creds, princ, NULL, 0, NULL, &options)))
        com_err(prog, retval, "while getting initial credentials");

    if ((retval = krb5_cc_initialize(context, cache, princ)))
        com_err(prog, retval, "while initializing credentials cache");

    if ((retval = krb5_cc_store_cred(context, cache, &creds)))
        com_err(prog, retval, "while storing credentials");

    krb5_free_cred_contents(context, &creds);
    krb5_free_principal(context, princ);
    krb5_cc_close(context, cache);
}
Ejemplo n.º 3
0
/* Inspired by krb5_verify_user from Heimdal */
static krb5_error_code verify_krb5_user(krb5_context context, krb5_principal principal, const char *password, krb5_principal server)
{
    krb5_creds creds;
    krb5_get_init_creds_opt gic_options;
    krb5_error_code ret;
    char *name = NULL;

    memset(&creds, 0, sizeof(creds));

    ret = krb5_unparse_name(context, principal, &name);
    if (ret == 0)
    {
#ifdef PRINTFS
        printf("Trying to get TGT for user %s\n", name);
#endif
        free(name);
    }

    krb5_get_init_creds_opt_init(&gic_options);
    ret = krb5_get_init_creds_password(context, &creds, principal, (char *)password, NULL, NULL, 0, NULL, &gic_options);
    if (ret)
    {
        set_basicauth_error(context, ret);
        goto end;
    }

end:
    krb5_free_cred_contents(context, &creds);

    return ret;
}
Ejemplo n.º 4
0
int
v5::renewCredential(krb5_context kcontext, krb5_principal kprincipal, krb5_timestamp *tgtEndtime)
{
	krb5_error_code         retval;
	krb5_creds              my_creds;
	krb5_ccache             ccache;
	krb5_get_init_creds_opt opts;
	
	qDebug("renew called");

	if (kprincipal == NULL)
	{
		qDebug("No principal name");

		return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
	}

	krb5_get_init_creds_opt_init(&opts);
	if (getTgtFromCcache (kcontext, &my_creds))
	{
		qDebug("got tgt from ccache");
		//setOptionsUsingCreds(kcontext, &my_creds, &opts);
		*tgtEndtime = my_creds.times.endtime;
		krb5_free_cred_contents(kcontext, &my_creds);
	}
	else
	{
		qDebug("TGT expired");
		*tgtEndtime = 0;
	}

	retval = krb5_cc_default(kcontext, &ccache);
	if (retval)
		return retval;

	retval = krb5_get_renewed_creds(kcontext, &my_creds, kprincipal, ccache,
	                                NULL);
	
	qDebug("krb5_get_renewed_creds returned: %d", retval);
	if (retval)
		goto out;
	
	retval = krb5_cc_initialize(kcontext, ccache, kprincipal);
	if (retval)
		goto out;
	
	retval = krb5_cc_store_cred(kcontext, ccache, &my_creds);
	if (retval)
		goto out;
	
	*tgtEndtime = my_creds.times.endtime;
	
out:
	krb5_free_cred_contents(kcontext, &my_creds);
	krb5_cc_close (kcontext, ccache);
	
	return retval;
}
Ejemplo n.º 5
0
/*
 * Allocate and initialize a krb5_get_init_creds_opt struct.  This code
 * assumes that an all-zero bit pattern will create a NULL pointer.
 */
krb5_error_code
krb5_get_init_creds_opt_alloc(krb5_context ctx UNUSED,
                              krb5_get_init_creds_opt **opts)
{
    *opts = calloc(1, sizeof(krb5_get_init_creds_opt));
    if (*opts == NULL)
        return errno;
    krb5_get_init_creds_opt_init(*opts);
    return 0;
}
Ejemplo n.º 6
0
static PyObject *
k5_change_password(PyObject *self, PyObject *args)
{
    int result_code;
    char *name, *oldpass, *newpass;
    krb5_context ctx;
    krb5_error_code code;
    krb5_principal principal;
    krb5_get_init_creds_opt options;
    krb5_creds creds;
    krb5_data result_code_string, result_string;

    if (!PyArg_ParseTuple(args, "sss", &name, &oldpass, &newpass))
        return NULL;

    /* Initialize parameters. */
    code = krb5_init_context(&ctx);
    RETURN_ON_ERROR("krb5_init_context()", code);
    code = krb5_parse_name(ctx, name, &principal);
    RETURN_ON_ERROR("krb5_parse_name()", code);

    /* Get credentials using the password. */
    krb5_get_init_creds_opt_init(&options);
    krb5_get_init_creds_opt_set_tkt_life(&options, 5*60);
    krb5_get_init_creds_opt_set_renew_life(&options, 0);
    krb5_get_init_creds_opt_set_forwardable(&options, 0);
    krb5_get_init_creds_opt_set_proxiable(&options, 0);
    memset(&creds, 0, sizeof (creds));
    code = krb5_get_init_creds_password(ctx, &creds, principal, oldpass,
					NULL, NULL, 0, "kadmin/changepw",
					&options);
    RETURN_ON_ERROR("krb5_get_init_creds_password()", code);

    code = krb5_change_password(ctx, &creds, newpass, &result_code,
				&result_code_string, &result_string);
    RETURN_ON_ERROR("krb5_change_password()", code);

    /* Any other error? */
    if (result_code != 0)
    {
	_k5_set_password_error(&result_code_string, &result_string);
	return NULL;
    }

    /* Free up results. */
    if (result_code_string.data != NULL)
	free(result_code_string.data);
    if (result_string.data != NULL)
	free(result_string.data);

    Py_INCREF(Py_None);
    return Py_None;
}
Ejemplo n.º 7
0
static PyObject *
k5_get_init_creds_keytab(PyObject *self, PyObject *args)
{
    char *name, *ktname;
    krb5_context ctx;
    krb5_error_code code;
    krb5_keytab keytab;
    krb5_ccache ccache;
    krb5_principal principal;
    krb5_get_init_creds_opt options;
    krb5_creds creds;

    if (!PyArg_ParseTuple(args, "sz", &name, &ktname))
        return NULL;

    /* Initialize parameters. */
    code = krb5_init_context(&ctx);
    RETURN_ON_ERROR("krb5_init_context()", code);
    code = krb5_parse_name(ctx, name, &principal);
    RETURN_ON_ERROR("krb5_parse_name()", code);
    krb5_get_init_creds_opt_init(&options);
    memset(&creds, 0, sizeof (creds));

    /* Resolve keytab */
    if (ktname)
    {
	code = krb5_kt_resolve(ctx, ktname, &keytab);
	RETURN_ON_ERROR("krb5_kt_resolve()", code);
    } else
    {
	code = krb5_kt_default(ctx, &keytab);
	RETURN_ON_ERROR("krb5_kt_resolve()", code);
    }

    /* Get the credentials. */
    code = krb5_get_init_creds_keytab(ctx, &creds, principal,
                                      keytab, 0, NULL, &options);
    RETURN_ON_ERROR("krb5_get_init_creds_keytab()", code);

    /* Store the credential in the credential cache. */
    code = krb5_cc_default(ctx, &ccache);
    RETURN_ON_ERROR("krb5_cc_default()", code);
    code = krb5_cc_initialize(ctx, ccache, principal);
    RETURN_ON_ERROR("krb5_cc_initialize()", code);
    code = krb5_cc_store_cred(ctx, ccache, &creds);
    RETURN_ON_ERROR("krb5_cc_store_creds()", code);
    krb5_cc_close(ctx, ccache);

    Py_INCREF(Py_None);
    return Py_None;
}
Ejemplo n.º 8
0
Archivo: sss_krb5.c Proyecto: 3van/sssd
krb5_error_code KRB5_CALLCONV sss_krb5_get_init_creds_opt_alloc(
                                                  krb5_context context,
                                                  krb5_get_init_creds_opt **opt)
{
#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC
    return krb5_get_init_creds_opt_alloc(context, opt);
#else
    *opt = calloc(1, sizeof(krb5_get_init_creds_opt));
    if (*opt == NULL) {
        return ENOMEM;
    }
    krb5_get_init_creds_opt_init(*opt);

    return 0;
#endif
}
Ejemplo n.º 9
0
/*
  simulate a kinit, putting the tgt in the given credentials cache.
  Orignally by [email protected]
*/
int kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc,
                               krb5_principal principal, const char *password,
                               time_t *expire_time, time_t *kdc_time)
{
    krb5_error_code code = 0;
    krb5_creds my_creds;
    krb5_get_init_creds_opt options;

    krb5_get_init_creds_opt_init(&options);

    krb5_get_init_creds_opt_set_default_flags(ctx, NULL, NULL, &options);

    if ((code = krb5_get_init_creds_password(ctx, &my_creds, principal, password,
                NULL,
                NULL, 0, NULL, &options))) {
        return code;
    }

    if ((code = krb5_cc_initialize(ctx, cc, principal))) {
        krb5_free_cred_contents(ctx, &my_creds);
        return code;
    }

    if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
        krb5_free_cred_contents(ctx, &my_creds);
        return code;
    }

    if (expire_time) {
        *expire_time = (time_t) my_creds.times.endtime;
    }

    if (kdc_time) {
        *kdc_time = (time_t) my_creds.times.starttime;
    }

    krb5_free_cred_contents(ctx, &my_creds);

    return 0;
}
Ejemplo n.º 10
0
static PyObject *
k5_get_init_creds_password(PyObject *self, PyObject *args)
{
    char *name, *password;
    krb5_context ctx;
    krb5_error_code code;
    krb5_ccache ccache;
    krb5_principal principal;
    krb5_get_init_creds_opt options;
    krb5_creds creds;

    if (!PyArg_ParseTuple(args, "ss", &name, &password))
        return NULL;

    /* Initialize parameters. */
    code = krb5_init_context(&ctx);
    RETURN_ON_ERROR("krb5_init_context()", code);
    code = krb5_parse_name(ctx, name, &principal);
    RETURN_ON_ERROR("krb5_parse_name()", code);
    krb5_get_init_creds_opt_init(&options);
    memset(&creds, 0, sizeof (creds));

    /* Get the credentials. */
    code = krb5_get_init_creds_password(ctx, &creds, principal, password,
                                        NULL, NULL, 0, NULL, &options);
    RETURN_ON_ERROR("krb5_get_init_creds_password()", code);

    /* Store the credential in the credential cache. */
    code = krb5_cc_default(ctx, &ccache);
    RETURN_ON_ERROR("krb5_cc_default()", code);
    code = krb5_cc_initialize(ctx, ccache, principal);
    RETURN_ON_ERROR("krb5_cc_initialize()", code);
    code = krb5_cc_store_cred(ctx, ccache, &creds);
    RETURN_ON_ERROR("krb5_cc_store_creds()", code);
    krb5_cc_close(ctx, ccache);

    Py_INCREF(Py_None);
    return Py_None;
}
Ejemplo n.º 11
0
 krb5_error_code smb_krb5_get_init_creds_opt_alloc(krb5_context context,
					    krb5_get_init_creds_opt **opt)
{
#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC
	/* Heimdal or modern MIT version */
	return krb5_get_init_creds_opt_alloc(context, opt);
#else
	/* Historical MIT version */
	krb5_get_init_creds_opt *my_opt;

	*opt = NULL;

	if ((my_opt = SMB_MALLOC(sizeof(krb5_get_init_creds_opt))) == NULL) {
		return ENOMEM;
	}

	krb5_get_init_creds_opt_init(my_opt);

	*opt =  my_opt;
	return 0;
#endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC  */
}
Ejemplo n.º 12
0
krb5_error_code KRB5_LIB_FUNCTION
krb5_get_init_creds_opt_alloc(krb5_context context, 
			      krb5_get_init_creds_opt **opt)
{
    krb5_get_init_creds_opt *o;
    
    *opt = NULL;
    o = calloc(1, sizeof(*o));
    if (o == NULL) {
	krb5_set_error_string(context, "out of memory");
	return ENOMEM;
    }
    krb5_get_init_creds_opt_init(o);
    o->opt_private = calloc(1, sizeof(*o->opt_private));
    if (o->opt_private == NULL) {
	krb5_set_error_string(context, "out of memory");
	free(o);
	return ENOMEM;
    }
    o->opt_private->refcount = 1;
    *opt = o;
    return 0;
}
Ejemplo n.º 13
0
static int
CommandProc(struct cmd_syndesc *as, void *arock)
{
    krb5_principal princ = 0;
    char *cell, *pname, **hrealms, *service;
    char service_temp[MAXKTCREALMLEN + 20];
    krb5_creds incred[1], mcred[1], *outcred = 0, *afscred;
    krb5_ccache cc = 0;
#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC
    krb5_get_init_creds_opt *gic_opts;
#else
    krb5_get_init_creds_opt gic_opts[1];
#endif
    char *tofree = NULL, *outname;
    int code;
    char *what;
    int i, dosetpag, evil, noprdb, id;
#ifdef AFS_RXK5
    int authtype;
#endif
    krb5_data enc_part[1];
    krb5_prompter_fct pf = NULL;
    char *pass = 0;
    void *pa = 0;
    struct kp_arg klog_arg[1];

    char passwd[BUFSIZ];
    struct afsconf_cell cellconfig[1];

    static char rn[] = "klog";	/*Routine name */
    static int Pipe = 0;	/* reading from a pipe */
    static int Silent = 0;	/* Don't want error messages */

    int writeTicketFile = 0;	/* write ticket file to /tmp */

    service = 0;
    memset(incred, 0, sizeof *incred);
    /* blow away command line arguments */
    for (i = 1; i < zero_argc; i++)
	memset(zero_argv[i], 0, strlen(zero_argv[i]));
    zero_argc = 0;
    memset(klog_arg, 0, sizeof *klog_arg);

    /* first determine quiet flag based on -silent switch */
    Silent = (as->parms[aSILENT].items ? 1 : 0);

    if (Silent) {
	afs_set_com_err_hook(silent_errors);
    }

    if ((code = krb5_init_context(&k5context))) {
	afs_com_err(rn, code, "while initializing Kerberos 5 library");
	KLOGEXIT(code);
    }
    if ((code = rx_Init(0))) {
	afs_com_err(rn, code, "while initializing rx");
	KLOGEXIT(code);
    }
    initialize_U_error_table();
    /*initialize_krb5_error_table();*/
    initialize_RXK_error_table();
    initialize_KTC_error_table();
    initialize_ACFG_error_table();
    /* initialize_rx_error_table(); */
    if (!(tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) {
	afs_com_err(rn, 0, "can't get afs configuration (afsconf_Open(%s))",
	    AFSDIR_CLIENT_ETC_DIRPATH);
	KLOGEXIT(1);
    }

    /*
     * Enable DES enctypes, which are currently still required for AFS.
     * krb5_allow_weak_crypto is MIT Kerberos 1.8.  krb5_enctype_enable is
     * Heimdal.
     */
#if defined(HAVE_KRB5_ENCTYPE_ENABLE)
    i = krb5_enctype_valid(k5context, ETYPE_DES_CBC_CRC);
    if (i)
        krb5_enctype_enable(k5context, ETYPE_DES_CBC_CRC);
#elif defined(HAVE_KRB5_ALLOW_WEAK_CRYPTO)
    krb5_allow_weak_crypto(k5context, 1);
#endif

    /* Parse remaining arguments. */

    dosetpag = !! as->parms[aSETPAG].items;
    Pipe = !! as->parms[aPIPE].items;
    writeTicketFile = !! as->parms[aTMP].items;
    noprdb = !! as->parms[aNOPRDB].items;
    evil = (always_evil&1) || !! as->parms[aUNWRAP].items;

#ifdef AFS_RXK5
    authtype = 0;
    if (as->parms[aK5].items)
	authtype |= FORCE_RXK5;
    if (as->parms[aK4].items)
	authtype |= FORCE_RXKAD;
    if (!authtype)
	authtype |= env_afs_rxk5_default();
#endif

    cell = as->parms[aCELL].items ? as->parms[aCELL].items->data : 0;
    if ((code = afsconf_GetCellInfo(tdir, cell, "afsprot", cellconfig))) {
	if (cell)
	    afs_com_err(rn, code, "Can't get cell information for '%s'", cell);
	else
	    afs_com_err(rn, code, "Can't get determine local cell!");
	KLOGEXIT(code);
    }

    if (as->parms[aKRBREALM].items) {
	code = krb5_set_default_realm(k5context,
		as->parms[aKRBREALM].items->data);
	if (code) {
	    afs_com_err(rn, code, "Can't make <%s> the default realm",
		as->parms[aKRBREALM].items->data);
	    KLOGEXIT(code);
	}
    }
    else if ((code = krb5_get_host_realm(k5context, cellconfig->hostName[0], &hrealms))) {
	afs_com_err(rn, code, "Can't get realm for host <%s> in cell <%s>\n",
		cellconfig->hostName[0], cellconfig->name);
	KLOGEXIT(code);
    } else {
	if (hrealms && *hrealms) {
	    code = krb5_set_default_realm(k5context,
		    *hrealms);
	    if (code) {
		afs_com_err(rn, code, "Can't make <%s> the default realm",
		    *hrealms);
		KLOGEXIT(code);
	    }
	}
	if (hrealms) krb5_free_host_realm(k5context, hrealms);
    }

    id = getuid();
    if (as->parms[aPRINCIPAL].items) {
	pname = as->parms[aPRINCIPAL].items->data;
    } else {
	/* No explicit name provided: use Unix uid. */
	struct passwd *pw;
	pw = getpwuid(id);
	if (pw == 0) {
	    afs_com_err(rn, 0,
		"Can't figure out your name from your user id (%d).", id);
	    if (!Silent)
		fprintf(stderr, "%s: Try providing the user name.\n", rn);
	    KLOGEXIT(1);
	}
	pname = pw->pw_name;
    }
    code = krb5_parse_name(k5context, pname, &princ);
    if (code) {
	afs_com_err(rn, code, "Can't parse principal <%s>", pname);
	KLOGEXIT(code);
    }

    if (as->parms[aPASSWORD].items) {
	/*
	 * Current argument is the desired password string.  Remember it in
	 * our local buffer, and zero out the argument string - anyone can
	 * see it there with ps!
	 */
	strncpy(passwd, as->parms[aPASSWORD].items->data, sizeof(passwd));
	memset(as->parms[aPASSWORD].items->data, 0,
	       strlen(as->parms[aPASSWORD].items->data));
	pass = passwd;
    }

    /* Get the password if it wasn't provided. */
    if (!pass) {
	if (Pipe) {
	    strncpy(passwd, getpipepass(), sizeof(passwd));
	    pass = passwd;
	} else {
	    pf = klog_prompter;
	    pa = klog_arg;
	}
    }

    service = 0;
#ifdef AFS_RXK5
    if (authtype & FORCE_RXK5) {
	tofree = get_afs_krb5_svc_princ(cellconfig);
	snprintf(service_temp, sizeof service_temp, "%s", tofree);
    } else
#endif
    snprintf (service_temp, sizeof service_temp, "afs/%s", cellconfig->name);

    klog_arg->pp = &pass;
    klog_arg->pstore = passwd;
    klog_arg->allocated = sizeof(passwd);
    /* XXX should allow k5 to prompt in most cases -- what about expired pw?*/
#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC
    code = krb5_get_init_creds_opt_alloc(k5context, &gic_opts);
    if (code) {
	afs_com_err(rn, code, "Can't allocate get_init_creds options");
	KLOGEXIT(code);
    }
#else
    krb5_get_init_creds_opt_init(gic_opts);
#endif

    for (;;) {
        code = krb5_get_init_creds_password(k5context,
	    incred,
	    princ,
	    pass,
	    pf,	/* prompter */
	    pa,	/* data */
	    0,	/* start_time */
	    0,	/* in_tkt_service */
	    gic_opts);
	if (code != KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN)
            break;
    }
    memset(passwd, 0, sizeof(passwd));
    if (code) {
	char *r = 0;
	if (krb5_get_default_realm(k5context, &r))
	    r = 0;
	if (r)
	    afs_com_err(rn, code, "Unable to authenticate in realm %s", r);
	else
	    afs_com_err(rn, code, "Unable to authenticate to use cell %s",
		cellconfig->name);
	if (r) free(r);
	KLOGEXIT(code);
    }

    for (;;writeTicketFile = 0) {
        if (writeTicketFile) {
            what = "getting default ccache";
            code = krb5_cc_default(k5context, &cc);
        } else {
            what = "krb5_cc_resolve";
            code = krb5_cc_resolve(k5context, "MEMORY:core", &cc);
            if (code) goto Failed;
        }
        what = "initializing ccache";
        code = krb5_cc_initialize(k5context, cc, princ);
        if (code) goto Failed;
        what = "writing Kerberos ticket file";
        code = krb5_cc_store_cred(k5context, cc, incred);
        if (code) goto Failed;
        if (writeTicketFile)
            fprintf(stderr,
                    "Wrote ticket file to %s\n",
                    krb5_cc_get_name(k5context, cc));
        break;
      Failed:
        if (code)
            afs_com_err(rn, code, "%s", what);
        if (writeTicketFile) {
            if (cc) {
                krb5_cc_close(k5context, cc);
                cc = 0;
            }
            continue;
        }
        KLOGEXIT(code);
    }

    for (service = service_temp;;service = "afs") {
        memset(mcred, 0, sizeof *mcred);
        mcred->client = princ;
        code = krb5_parse_name(k5context, service, &mcred->server);
        if (code) {
            afs_com_err(rn, code, "Unable to parse service <%s>\n", service);
            KLOGEXIT(code);
        }
        if (tofree) { free(tofree); tofree = 0; }
        if (!(code = krb5_unparse_name(k5context, mcred->server, &outname)))
            tofree = outname;
        else outname = service;
        code = krb5_get_credentials(k5context, 0, cc, mcred, &outcred);
        krb5_free_principal(k5context, mcred->server);
        if (code != KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN || service != service_temp) break;
#ifdef AFS_RXK5
        if (authtype & FORCE_RXK5)
            break;
#endif
    }
    afscred = outcred;

    if (code) {
	afs_com_err(rn, code, "Unable to get credentials to use %s", outname);
	KLOGEXIT(code);
    }

#ifdef AFS_RXK5
    if (authtype & FORCE_RXK5) {
	struct ktc_principal aserver[1];
	int viceid = 555;

	memset(aserver, 0, sizeof *aserver);
	strncpy(aserver->cell, cellconfig->name, MAXKTCREALMLEN-1);
	code = ktc_SetK5Token(k5context, aserver, afscred, viceid, dosetpag);
	if (code) {
	    afs_com_err(rn, code, "Unable to store tokens for cell %s\n",
		cellconfig->name);
	    KLOGEXIT(1);
	}
    } else
#endif
    {
	struct ktc_principal aserver[1], aclient[1];
	struct ktc_token atoken[1];

	memset(atoken, 0, sizeof *atoken);
	if (evil) {
	    size_t elen = enc_part->length;
	    atoken->kvno = RXKAD_TKT_TYPE_KERBEROS_V5_ENCPART_ONLY;
	    if (afs_krb5_skip_ticket_wrapper(afscred->ticket.data,
			afscred->ticket.length, (char **) &enc_part->data,
			&elen)) {
		afs_com_err(rn, 0, "Can't unwrap %s AFS credential",
		    cellconfig->name);
		KLOGEXIT(1);
	    }
	} else {
	    atoken->kvno = RXKAD_TKT_TYPE_KERBEROS_V5;
	    *enc_part = afscred->ticket;
	}
	atoken->startTime = afscred->times.starttime;
	atoken->endTime = afscred->times.endtime;
	if (tkt_DeriveDesKey(get_creds_enctype(afscred),
			     get_cred_keydata(afscred),
			     get_cred_keylen(afscred), &atoken->sessionKey)) {
	    afs_com_err(rn, 0,
			"Cannot derive DES key from enctype %i of length %u",
			get_creds_enctype(afscred),
			(unsigned)get_cred_keylen(afscred));
	    KLOGEXIT(1);
	}
	memcpy(atoken->ticket, enc_part->data,
	    atoken->ticketLen = enc_part->length);
	memset(aserver, 0, sizeof *aserver);
	strncpy(aserver->name, "afs", 4);
	strncpy(aserver->cell, cellconfig->name, MAXKTCREALMLEN-1);
	memset(aclient, 0, sizeof *aclient);
	i = realm_len(k5context, afscred->client);
	if (i > MAXKTCREALMLEN-1) i = MAXKTCREALMLEN-1;
	memcpy(aclient->cell, realm_data(k5context, afscred->client), i);
	if (!noprdb) {
	    int viceid = 0;
	    k5_to_k4_name(k5context, afscred->client, aclient);
	    code = whoami(atoken, cellconfig, aclient, &viceid);
	    if (code) {
		afs_com_err(rn, code, "Can't get your viceid for cell %s", cellconfig->name);
		*aclient->name = 0;
	    } else
		snprintf(aclient->name, MAXKTCNAMELEN-1, "AFS ID %d", viceid);
	}
	if (!*aclient->name)
	    k5_to_k4_name(k5context, afscred->client, aclient);
	code = ktc_SetToken(aserver, atoken, aclient, dosetpag);
	if (code) {
	    afs_com_err(rn, code, "Unable to store tokens for cell %s\n",
		cellconfig->name);
	    KLOGEXIT(1);
	}
    }

    krb5_free_principal(k5context, princ);
    krb5_free_cred_contents(k5context, incred);
    if (outcred) krb5_free_creds(k5context, outcred);
    if (cc)
	krb5_cc_close(k5context, cc);
    if (tofree) free(tofree);

    return 0;
}
Ejemplo n.º 14
0
    int
cosign_login_krb5( struct connlist *head, char *cosignname, char *id, 
	char *realm, char *passwd, char *ip_addr, char *cookie, 
	struct subparams *sp, char **msg )
{
    krb5_error_code             kerror = 0;
    krb5_context                kcontext;
    krb5_principal              kprinc;
    krb5_principal              sprinc;
    krb5_get_init_creds_opt     kopts;
    krb5_verify_init_creds_opt 	kvic_opts[ 1 ];
    krb5_creds                  kcreds;
    krb5_ccache                 kccache;
    krb5_keytab                 keytab = 0;
    char			*tmpl = ERROR_HTML; 
    char			*sprinc_name = NULL;
    char                        ktbuf[ MAX_KEYTAB_NAME_LEN + 1 ];
    char                        tmpkrb[ 16 ], krbpath [ MAXPATHLEN ];
    int				i;

    lcgi_configure();

    if (( kerror = krb5_init_context( &kcontext ))) {
	sl[ SL_ERROR ].sl_data = (char *)error_message( kerror );
	sl[ SL_TITLE ].sl_data = "Authentication Required ( kerberos error )";
	subfile( tmpl, sl, 0 );
	exit( 0 );
    }

    if (( kerror = krb5_parse_name( kcontext, id, &kprinc ))) {
	sl[ SL_ERROR ].sl_data = (char *)error_message( kerror );
	sl[ SL_TITLE ].sl_data = "Authentication Required ( kerberos error )";
	subfile( tmpl, sl, 0 );
	exit( 0 );
    }

    /* need to get realm out */
    if ( realm == NULL || *realm == '\0' ) {
	if (( kerror = krb5_get_default_realm( kcontext, &realm )) != 0 ) {
	    sl[ SL_ERROR ].sl_data = (char *)error_message( kerror );
 	    sl[ SL_TITLE ].sl_data = "Authentication Required "
		    "( krb realm error )";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
    	}
    }

    if ( store_tickets ) {
	if ( mkcookie( sizeof( tmpkrb ), tmpkrb ) != 0 ) {
	    sl[ SL_ERROR ].sl_data = "An unknown error occurred.";
	    sl[ SL_TITLE ].sl_data = "Authentication Required (kerberos error)";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
	}

	if ( snprintf( krbpath, sizeof( krbpath ), "%s/%s",
		ticket_path, tmpkrb ) >= sizeof( krbpath )) {
	    sl[ SL_ERROR ].sl_data = "An unknown error occurred.";
	    sl[ SL_TITLE ].sl_data = "Authentication Required (krbpath error)";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
	}

	if (( kerror = krb5_cc_resolve( kcontext, krbpath, &kccache )) != 0 ) {
	    sl[ SL_ERROR ].sl_data = (char *)error_message( kerror );
	    sl[ SL_TITLE ].sl_data = "Authentication Required (kerberos error)";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
	}
    }

    krb5_get_init_creds_opt_init( &kopts );
    krb5_get_init_creds_opt_set_tkt_life( &kopts, tkt_life );
    krb5_get_init_creds_opt_set_renew_life( &kopts, 0 );
    krb5_get_init_creds_opt_set_forwardable( &kopts, 1 );
    krb5_get_init_creds_opt_set_proxiable( &kopts, 0 );

    if (( kerror = krb5_get_init_creds_password( kcontext, &kcreds, 
	    kprinc, passwd, NULL, NULL, 0, NULL /*keytab */, &kopts ))) {

	if (( kerror == KRB5KRB_AP_ERR_BAD_INTEGRITY ) ||
		( kerror == KRB5KDC_ERR_PREAUTH_FAILED ) ||
		( kerror == KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN )) {
	    return( COSIGN_CGI_ERROR );	/* draw login or reauth page */
        } else if ( kerror == KRB5KDC_ERR_KEY_EXP ) {
	    *msg = (char *)error_message( kerror );
            return( COSIGN_CGI_PASSWORD_EXPIRED );
	} else {
	    sl[ SL_ERROR ].sl_data = (char *)error_message( kerror );
	    sl[ SL_TITLE ].sl_data = "Error";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
	}
    }

    /* verify no KDC spoofing */
    if ( *keytab_path != '\0' ) {
	if ( strlen( keytab_path ) > MAX_KEYTAB_NAME_LEN ) {
	    sl[ SL_ERROR ].sl_data = "server configuration error";
	    sl[ SL_TITLE ].sl_data = "Ticket Verification Error";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
	}
	strcpy( ktbuf, keytab_path );

	/* from mdw */
	krb5_verify_init_creds_opt_init( kvic_opts );
	krb5_verify_init_creds_opt_set_ap_req_nofail( kvic_opts, 1 );

	if (( kerror = krb5_kt_resolve( kcontext, ktbuf, &keytab )) != 0 ) {
	    sl[ SL_ERROR ].sl_data = (char *)error_message( kerror );
	    sl[ SL_TITLE ].sl_data = "KT Resolve Error";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
	}

	if ( cosign_princ ) {
	    kerror = krb5_parse_name( kcontext, cosign_princ, &sprinc );
	} else {
	    kerror = krb5_sname_to_principal( kcontext, NULL, "cosign",
			KRB5_NT_SRV_HST, &sprinc );
	}
	if ( kerror != 0 ) {
	    sl[ SL_ERROR ].sl_data = (char *)error_message( kerror );
	    sl[ SL_TITLE ].sl_data = "Server Principal Error";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
	}

	if (( kerror = krb5_verify_init_creds(
		kcontext, &kcreds, sprinc, keytab, NULL, kvic_opts )) != 0 ) {
	    if ( krb5_unparse_name( kcontext, sprinc, &sprinc_name ) == 0 ) {
		fprintf( stderr, "ticket verify error for "
			 "user %s, keytab principal %s", id, sprinc_name );
		free( sprinc_name );
	    } else {
		fprintf( stderr, "ticket verify error for user %s", id );
	    }
	    sl[ SL_ERROR ].sl_data = (char *)error_message( kerror );
	    sl[ SL_TITLE ].sl_data = "Ticket Verify Error";
	    subfile( tmpl, sl, 0 );
	    krb5_free_principal( kcontext, sprinc );
	    exit( 0 );
	}
	(void)krb5_kt_close( kcontext, keytab );
	krb5_free_principal( kcontext, sprinc );
    }

    for ( i = 0; i < COSIGN_MAXFACTORS - 1; i++ ) {
	if ( new_factors[ i ] == NULL ) {
	    new_factors[ i ] = strdup( realm );
	    new_factors[ i + 1 ] = NULL;
	    break;
	}
	if ( strcmp( new_factors[ i ], realm ) == 0 ) {
	    break;
	}
    }

    if ( sp->sp_reauth && sp->sp_ipchanged == 0 ) {
	return( COSIGN_CGI_OK );
    }

    if ( store_tickets ) {
	if (( kerror = krb5_cc_initialize( kcontext, kccache, kprinc )) != 0 ) {
	    sl[ SL_ERROR ].sl_data = (char *)error_message( kerror );
	    sl[ SL_TITLE ].sl_data = "CC Initialize Error";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
	}
	if (( kerror = krb5_cc_store_cred( kcontext, kccache, &kcreds ))
		!= 0 ) {
	    sl[ SL_ERROR ].sl_data = (char *)error_message( kerror );
	    sl[ SL_TITLE ].sl_data = "CC Storing Error";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
	}
	krb5_cc_close( kcontext, kccache );
    }

    krb5_free_cred_contents( kcontext, &kcreds );
    krb5_free_principal( kcontext, kprinc );
    krb5_free_context( kcontext );

    /* password has been accepted, tell cosignd */
    if ( cosign_login( head, cookie, ip_addr, cosignname, realm, 
	    ( store_tickets ? krbpath : NULL )) < 0 ) {
	fprintf( stderr, "cosign_login_krb5: login failed\n") ;
	sl[ SL_ERROR ].sl_data = "We were unable to contact the "
		"authentication server. Please try again later.";
	sl[ SL_TITLE ].sl_data = "Error: Please try later";
	subfile( tmpl, sl, 0 );
	exit( 0 );
    }

    return( COSIGN_CGI_OK );
}
Ejemplo n.º 15
0
static ADS_STATUS ads_krb5_chg_password(const char *kdc_host,
					const char *principal,
					const char *oldpw, 
					const char *newpw, 
					int time_offset)
{
    ADS_STATUS aret;
    krb5_error_code ret;
    krb5_context context = NULL;
    krb5_principal princ;
    krb5_get_init_creds_opt opts;
    krb5_creds creds;
    char *chpw_princ = NULL, *password;
    char *realm = NULL;
    int result_code;
    krb5_data result_code_string = { 0 };
    krb5_data result_string = { 0 };
    smb_krb5_addresses *addr = NULL;

    initialize_krb5_error_table();
    ret = krb5_init_context(&context);
    if (ret) {
	DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret)));
	return ADS_ERROR_KRB5(ret);
    }

    if ((ret = smb_krb5_parse_name(context, principal,
                                    &princ))) {
	krb5_free_context(context);
	DEBUG(1,("Failed to parse %s (%s)\n", principal, error_message(ret)));
	return ADS_ERROR_KRB5(ret);
    }

    krb5_get_init_creds_opt_init(&opts);

    krb5_get_init_creds_opt_set_tkt_life(&opts, 5*60);
    krb5_get_init_creds_opt_set_renew_life(&opts, 0);
    krb5_get_init_creds_opt_set_forwardable(&opts, 0);
    krb5_get_init_creds_opt_set_proxiable(&opts, 0);

    /* note that heimdal will fill in the local addresses if the addresses
     * in the creds_init_opt are all empty and then later fail with invalid
     * address, sending our local netbios krb5 address - just like windows
     * - avoids this - gd */
    ret = smb_krb5_gen_netbios_krb5_address(&addr, lp_netbios_name());
    if (ret) {
        krb5_free_principal(context, princ);
        krb5_free_context(context);
        return ADS_ERROR_KRB5(ret);
    }
    krb5_get_init_creds_opt_set_address_list(&opts, addr->addrs);

    realm = smb_krb5_principal_get_realm(context, princ);

    /* We have to obtain an INITIAL changepw ticket for changing password */
    if (asprintf(&chpw_princ, "kadmin/changepw@%s", realm) == -1) {
	krb5_free_context(context);
	free(realm);
	DEBUG(1,("ads_krb5_chg_password: asprintf fail\n"));
	return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
    }

    free(realm);
    password = SMB_STRDUP(oldpw);
    ret = krb5_get_init_creds_password(context, &creds, princ, password,
					   kerb_prompter, NULL, 
					   0, chpw_princ, &opts);
    SAFE_FREE(chpw_princ);
    SAFE_FREE(password);

    if (ret) {
      if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY)
	DEBUG(1,("Password incorrect while getting initial ticket"));
      else
	DEBUG(1,("krb5_get_init_creds_password failed (%s)\n", error_message(ret)));

	krb5_free_principal(context, princ);
	krb5_free_context(context);
	return ADS_ERROR_KRB5(ret);
    }

    ret = krb5_change_password(context,
			       &creds,
			       discard_const_p(char, newpw),
			       &result_code,
			       &result_code_string,
			       &result_string);
    if (ret) {
	DEBUG(1, ("krb5_change_password failed (%s)\n", error_message(ret)));
	aret = ADS_ERROR_KRB5(ret);
	goto done;
    }

    if (result_code != KRB5_KPASSWD_SUCCESS) {
	ret = kpasswd_err_to_krb5_err(result_code);
	DEBUG(1, ("krb5_change_password failed (%s)\n", error_message(ret)));
	aret = ADS_ERROR_KRB5(ret);
	goto done;
    }

    aret = ADS_SUCCESS;

done:
    kerberos_free_data_contents(context, &result_code_string);
    kerberos_free_data_contents(context, &result_string);
    krb5_free_principal(context, princ);
    krb5_free_context(context);

    return aret;
}
Ejemplo n.º 16
0
static int chk_kerberos(
	const struct berval *sc,
	const struct berval * passwd,
	const struct berval * cred,
	const char **text )
{
	unsigned int i;
	int rtn;

	for( i=0; i<cred->bv_len; i++) {
		if(cred->bv_val[i] == '\0') {
			return LUTIL_PASSWD_ERR;	/* NUL character in password */
		}
	}

	if( cred->bv_val[i] != '\0' ) {
		return LUTIL_PASSWD_ERR;	/* cred must behave like a string */
	}

	for( i=0; i<passwd->bv_len; i++) {
		if(passwd->bv_val[i] == '\0') {
			return LUTIL_PASSWD_ERR;	/* NUL character in password */
		}
	}

	if( passwd->bv_val[i] != '\0' ) {
		return LUTIL_PASSWD_ERR;	/* passwd must behave like a string */
	}

	rtn = LUTIL_PASSWD_ERR;

#ifdef HAVE_KRB5 /* HAVE_HEIMDAL_KRB5 */
	{
/* Portions:
 * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska H\xf6gskolan
 * (Royal Institute of Technology, Stockholm, Sweden).
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the Institute nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

		krb5_context context;
   		krb5_error_code ret;
   		krb5_creds creds;
   		krb5_get_init_creds_opt get_options;
   		krb5_verify_init_creds_opt verify_options;
		krb5_principal client, server;
#ifdef notdef
		krb5_preauthtype pre_auth_types[] = {KRB5_PADATA_ENC_TIMESTAMP};
#endif

		ret = krb5_init_context( &context );
		if (ret) {
			return LUTIL_PASSWD_ERR;
		}

#ifdef notdef
		krb5_get_init_creds_opt_set_preauth_list(&get_options,
			pre_auth_types, 1);
#endif

   		krb5_get_init_creds_opt_init( &get_options );

		krb5_verify_init_creds_opt_init( &verify_options );
	
		ret = krb5_parse_name( context, passwd->bv_val, &client );

		if (ret) {
			krb5_free_context( context );
			return LUTIL_PASSWD_ERR;
		}

		ret = krb5_get_init_creds_password( context,
			&creds, client, cred->bv_val, NULL,
			NULL, 0, NULL, &get_options );

		if (ret) {
			krb5_free_principal( context, client );
			krb5_free_context( context );
			return LUTIL_PASSWD_ERR;
		}

		{
			char *host = ldap_pvt_get_fqdn( NULL );

			if( host == NULL ) {
				krb5_free_principal( context, client );
				krb5_free_context( context );
				return LUTIL_PASSWD_ERR;
			}

			ret = krb5_sname_to_principal( context,
				host, "ldap", KRB5_NT_SRV_HST, &server );

			ber_memfree( host );
		}

		if (ret) {
			krb5_free_principal( context, client );
			krb5_free_context( context );
			return LUTIL_PASSWD_ERR;
		}

		ret = krb5_verify_init_creds( context,
			&creds, server, NULL, NULL, &verify_options );

		krb5_free_principal( context, client );
		krb5_free_principal( context, server );
		krb5_free_cred_contents( context, &creds );
		krb5_free_context( context );

		rtn = ret ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
	}
#elif	defined(HAVE_KRB4)
	{
		/* Borrowed from Heimdal kpopper */
/* Portions:
 * Copyright (c) 1989 Regents of the University of California.
 * All rights reserved.  The Berkeley software License Agreement
 * specifies the terms and conditions for redistribution.
 */

		int status;
		char lrealm[REALM_SZ];
		char tkt[MAXHOSTNAMELEN];

		status = krb_get_lrealm(lrealm,1);
		if (status == KFAILURE) {
			return LUTIL_PASSWD_ERR;
		}

		snprintf(tkt, sizeof(tkt), "%s_slapd.%u",
			TKT_ROOT, (unsigned)getpid());
		krb_set_tkt_string (tkt);

		status = krb_verify_user( passwd->bv_val, "", lrealm,
			cred->bv_val, 1, "ldap");

		dest_tkt(); /* no point in keeping the tickets */

		return status == KFAILURE ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
	}
#endif

	return rtn;
}
Ejemplo n.º 17
0
krb5_error_code
kcm_ccache_acquire(krb5_context context,
		   kcm_ccache ccache,
		   krb5_creds **credp)
{
    krb5_error_code ret = 0;
    krb5_creds cred;
    krb5_const_realm realm;
    krb5_get_init_creds_opt opt;
    krb5_ccache_data ccdata;
    char *in_tkt_service = NULL;
    int done = 0;

    memset(&cred, 0, sizeof(cred));

    KCM_ASSERT_VALID(ccache);

    /* We need a cached key or keytab to acquire credentials */
    if (ccache->flags & KCM_FLAGS_USE_CACHED_KEY) {
	if (ccache->key.keyblock.keyvalue.length == 0)
	    krb5_abortx(context,
			"kcm_ccache_acquire: KCM_FLAGS_USE_CACHED_KEY without key");
    } else if (ccache->flags & KCM_FLAGS_USE_KEYTAB) {
	if (ccache->key.keytab == NULL)
	    krb5_abortx(context,
			"kcm_ccache_acquire: KCM_FLAGS_USE_KEYTAB without keytab");
    } else {
	kcm_log(0, "Cannot acquire initial credentials for cache %s without key",
		ccache->name);
	return KRB5_FCC_INTERNAL;
    }
	
    HEIMDAL_MUTEX_lock(&ccache->mutex);

    /* Fake up an internal ccache */
    kcm_internal_ccache(context, ccache, &ccdata);

    /* Now, actually acquire the creds */
    if (ccache->server != NULL) {
	ret = krb5_unparse_name(context, ccache->server, &in_tkt_service);
	if (ret) {
	    kcm_log(0, "Failed to unparse service principal name for cache %s: %s",
		    ccache->name, krb5_get_err_text(context, ret));
	    return ret;
	}
    }

    realm = krb5_principal_get_realm(context, ccache->client);

    krb5_get_init_creds_opt_init(&opt);
    krb5_get_init_creds_opt_set_default_flags(context, "kcm", realm, &opt);
    if (ccache->tkt_life != 0)
	krb5_get_init_creds_opt_set_tkt_life(&opt, ccache->tkt_life);
    if (ccache->renew_life != 0)
	krb5_get_init_creds_opt_set_renew_life(&opt, ccache->renew_life);

    if (ccache->flags & KCM_FLAGS_USE_CACHED_KEY) {
	ret = krb5_get_init_creds_keyblock(context,
					   &cred,
					   ccache->client,
					   &ccache->key.keyblock,
					   0,
					   in_tkt_service,
					   &opt);
    } else {
	/* loosely based on lib/krb5/init_creds_pw.c */
	while (!done) {
	    ret = krb5_get_init_creds_keytab(context,
					     &cred,
					     ccache->client,
					     ccache->key.keytab,
					     0,
					     in_tkt_service,
					     &opt);
	    switch (ret) {
	    case KRB5KDC_ERR_KEY_EXPIRED:
		if (in_tkt_service != NULL &&
		    strcmp(in_tkt_service, "kadmin/changepw") == 0) {
		    goto out;
		}

		ret = change_pw_and_update_keytab(context, ccache);
		if (ret)
		    goto out;
		break;
	    case 0:
	    default:
		done = 1;
		break;
	    }
	}
    }

    if (ret) {
	kcm_log(0, "Failed to acquire credentials for cache %s: %s",
		ccache->name, krb5_get_err_text(context, ret));
	if (in_tkt_service != NULL)
	    free(in_tkt_service);
	goto out;
    }

    if (in_tkt_service != NULL)
	free(in_tkt_service);

    /* Swap them in */
    kcm_ccache_remove_creds_internal(context, ccache);

    ret = kcm_ccache_store_cred_internal(context, ccache, &cred, 0, credp);
    if (ret) {
	kcm_log(0, "Failed to store credentials for cache %s: %s",
		ccache->name, krb5_get_err_text(context, ret));
	krb5_free_cred_contents(context, &cred);
	goto out;
    }

out:
    HEIMDAL_MUTEX_unlock(&ccache->mutex);

    return ret;
}
Ejemplo n.º 18
0
static void do_renew(GtkWidget *widget, GtkWidget *entry)
{
  char *pass;
  krb5_error_code code;
  krb5_context kcontext;
  krb5_principal me = NULL;
  char *service_name = NULL;
  krb5_ccache ccache = NULL;
  krb5_creds my_creds;
  char *msg = NULL;
  krb5_deltat start_time = 0;
  krb5_deltat lifetime = 10 * 60 * 60;
  krb5_get_init_creds_opt opts;
  int non_fatal = 0;

  pass = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
  gtk_entry_set_text(GTK_ENTRY(entry), "");

  krb5_get_init_creds_opt_init(&opts);

  if (!pass || !strlen(pass))
    {
      non_fatal = 1;
      msg = g_strdup("Incorrect password: please try again.");
    }
  else if ((code = krb5_init_context(&kcontext)))
    msg = g_strdup_printf("%s when initializing kerberos library",
			  error_message(code));
  else if ((code = krb5_cc_default(kcontext, &ccache)))
    msg = g_strdup_printf("%s while getting default cache.",
			  error_message(code));
  else if ((code = krb5_parse_name(kcontext, name, &me)))
    msg = g_strdup_printf("%s while parsing name %s.", error_message(code),
			  name);
  else if ((code = krb5_get_init_creds_password(kcontext,
						&my_creds, me, pass,
						krb5_prompter_posix, NULL,
						start_time, service_name,
						&opts)))
    {
      if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY)
	{
	  non_fatal = 1;
	  msg = g_strdup("Incorrect password: please try again.");
	}
      else
	{
	  msg = g_strdup_printf("%s while getting initial"
				" credentials", error_message(code));
	}
    }
  else
    {
      if ((code = krb5_cc_initialize(kcontext, ccache, me)))
	{
	  msg = g_strdup_printf("%s while initializing cache",
				error_message(code));
	}
      else if ((code = krb5_cc_store_cred(kcontext, ccache,
					  &my_creds)))
	{
	  msg = g_strdup_printf("%s while storing credentials",
				error_message(code));
	}
      else
	{
	  if (me)
	    krb5_free_principal(kcontext, me);
	  if (ccache)
	    krb5_cc_close(kcontext, ccache);

	  krb5_free_context(kcontext);
	}
    }

  g_free(pass);

  if (msg)
    {
      /* encountered an error. don't quit */
      if (non_fatal)
	do_error_dialog(msg);
      else
	do_fatal_dialog(msg);
      g_free(msg);
    }
  else
    /* no errors, we're done */
    {
      system("fsid -a > /dev/null");
      system("zctl load /dev/null > /dev/null");
      exit(0);
    }
}
Ejemplo n.º 19
0
int do_command(krb5_context context, krb5_keytab keytab, krb5_principal me, char *princ, char *cmd, char *cmddir) {
	char *p;
	char *answer;
	static char answer_exec[] = "Cannot execute command.";
	static char answer_priv[] = "You are not privileged to execute this command.";
	static char answer_regexp[] = "Command doesn't match any allowed regexp.";
	int result;

	if (debug)
		syslog(LOG_DEBUG, "Principal %s is trying to execute command %s", princ, cmd);

	/* Replace \n with \0 */
	p = cmd;
	while (*p != '\0' && *p != '\n')
		p++;
	*p = '\0';

	if (gethelp(cmd) == 0)
		return 0;

	if ((result = chk_user_cmd(princ, cmd)) != 0) {
		switch(result) {
			case CHK_GRP:
				answer = answer_priv;
				break;
			case CHK_REGEXP:
				answer = answer_regexp;
				break;
			default:
				answer = answer_exec;
		}
		if (debug)
			syslog(LOG_DEBUG, "%s", answer);
		if (write(1, answer, strlen(answer)) == -1)
			printf("Failed write to stdout.\n");
		return 0;
	} else {
		char *localcmd, *pathenv;
		char ccname[255];
		krb5_ccache ccache;
		krb5_creds creds;
		krb5_principal tgtserver;
		krb5_error_code retval;
		krb5_get_init_creds_opt opts;

		pathenv = malloc((strlen(cmddir) + 6) * sizeof(char));
		if (pathenv == NULL) {
			syslog(LOG_ERR, "Not enough memory (env)");
			exit(1);
		}
		sprintf(pathenv, "PATH=%s", cmddir);

		preauth = preauth_list;
#ifdef __osf__
		sprintf(ccname, "FILE:/tmp/afsadm_%d", getpid());
#else
		snprintf(ccname, 255, "FILE:/tmp/afsadm_%d", getpid());
#endif
		if (retval = krb5_cc_resolve(context, ccname, &ccache)) {
			syslog(LOG_ERR, "%s while resolving ccache", error_message(retval));
			exit(1);
		}
#ifdef __osf__
		sprintf(ccname, "KRB5CCNAME=FILE:/tmp/afsadm_%d", getpid());
#else
		snprintf(ccname, 255, "KRB5CCNAME=FILE:/tmp/afsadm_%d", getpid());
#endif

		putenv(ccname);
		if (retval = krb5_cc_initialize(context, ccache, me)) {
			syslog(LOG_ERR, "%s while initialize ccache", error_message(retval));
			exit(1);
		}

		memset((char *)&creds, 0, sizeof(creds));
		creds.client = me;

		krb5_data *realm = krb5_princ_realm(context, me);

		if ((retval = krb5_build_principal_ext(context, &tgtserver, realm->length, realm->data, tgtname.length, tgtname.data, realm->length, realm->data, 0))) {
			syslog(LOG_ERR, "%s while building server name", error_message(retval));
			krb5_cc_destroy(context, ccache);
			exit(1);
		}

		creds.server = tgtserver;

		krb5_get_init_creds_opt_init(&opts);
		opts.preauth_list = preauth;

		if (retval = krb5_get_init_creds_keytab(context, &creds, me, keytab, 0, NULL, &opts)) {
			syslog(LOG_ERR, "%s while getting tgt", error_message(retval));
			krb5_cc_destroy(context, ccache);
			exit(1);
		}

		if (retval = krb5_cc_store_cred(context, ccache, &creds)) {
			syslog(LOG_ERR, "%s while saving credentials to ccache", error_message(retval));
			krb5_cc_destroy(context, ccache);
			exit(1);
		}

		if (k_hasafs())
			k_setpag();

		localcmd = malloc(sizeof(char) * (strlen(cmd) + strlen(cmddir) + 2));
		if (localcmd == NULL) {
			syslog(LOG_ERR, "Not enough memory (cmdpath malloc)");
			exit(1);
		}
		sprintf(localcmd, "%s/%s", cmddir, cmd);

		syslog(LOG_INFO, "Principal %s : system(%s)", princ, localcmd);

		/* Set PATH to dircmd !!!! */
		putenv(pathenv);
		//system("/usr/bin/id -a; aklog");

		if (system("aklog") == -1)
			printf("Cannot execute aklog.\n");
		result = system(localcmd);

		syslog(LOG_INFO, "Principal %s : system(%s) returns with %d", princ, localcmd, result);

		free(pathenv);
		free(localcmd);

		if (k_hasafs())
			k_unlog();

		krb5_cc_destroy(context, ccache);
		return 0;
	}
}
Ejemplo n.º 20
0
Archivo: cns.c Proyecto: Akasurde/krb5
/*
 * Function: Process WM_COMMAND messages
 */
static void
kwin_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify)
{
  char                      name[ANAME_SZ];
  char                      realm[REALM_SZ];
  char                      password[MAX_KPW_LEN];
  HCURSOR                   hcursor;
  BOOL                      blogin;
  HMENU                     hmenu;
  char                      menuitem[MAX_K_NAME_SZ + 3];
  char                      copyright[128];
  int                       id;
#ifdef KRB4
  char                      instance[INST_SZ];
  int                       lifetime;
  int                       krc;
#endif
#ifdef KRB5
  long                      lifetime;
  krb5_error_code           code;
  krb5_principal            principal;
  krb5_creds                creds;
  krb5_get_init_creds_opt   opts;
  gic_data                  gd;
#endif

#ifdef KRB4
  EnableWindow(GetDlgItem(hwnd, IDD_TICKET_DELETE), krb_get_num_cred() > 0);
#endif

#ifdef KRB5
  EnableWindow(GetDlgItem(hwnd, IDD_TICKET_DELETE), k5_get_num_cred(1) > 0);
#endif

  GetDlgItemText(hwnd, IDD_LOGIN_NAME, name, sizeof(name));
  trim(name);
  blogin = strlen(name) > 0;

  if (blogin) {
    GetDlgItemText(hwnd, IDD_LOGIN_REALM, realm, sizeof(realm));
    trim(realm);
    blogin = strlen(realm) > 0;
  }

  if (blogin) {
    GetDlgItemText(hwnd, IDD_LOGIN_PASSWORD, password, sizeof(password));
    blogin = strlen(password) > 0;
  }

  EnableWindow(GetDlgItem(hwnd, IDD_LOGIN), blogin);
  id = (blogin) ? IDD_LOGIN : IDD_PASSWORD_CR2;
  SendMessage(hwnd, DM_SETDEFID, id, 0);

  if (codeNotify != BN_CLICKED && codeNotify != 0 && codeNotify != 1)
    return; /* FALSE */

  /*
   * Check to see if this item is in a list of the ``recent hosts'' sort
   * of list, under the FILE menu.
   */
  if (cid >= IDM_FIRST_LOGIN && cid < IDM_FIRST_LOGIN + FILE_MENU_MAX_LOGINS) {
    hmenu = GetMenu(hwnd);
    assert(hmenu != NULL);

    hmenu = GetSubMenu(hmenu, 0);
    assert(hmenu != NULL);

    if (!GetMenuString(hmenu, cid, menuitem, sizeof(menuitem), MF_BYCOMMAND))
      return; /* TRUE */

    if (menuitem[0])
      kwin_init_name(hwnd, &menuitem[3]);

    return; /* TRUE */
  }

  switch (cid) {
  case IDM_EXIT:
    if (isblocking)
      WSACancelBlockingCall();
    WinHelp(hwnd, KERBEROS_HLP, HELP_QUIT, 0);
    PostQuitMessage(0);

    return; /* TRUE */

  case IDD_PASSWORD_CR2:                      /* Make CR == TAB */
    id = GetDlgCtrlID(GetFocus());
    assert(id != 0);

    if (id == IDD_MAX_EDIT)
      PostMessage(hwnd, WM_NEXTDLGCTL,
		  (WPARAM)GetDlgItem(hwnd, IDD_MIN_EDIT), MAKELONG(1, 0));
    else
      PostMessage(hwnd, WM_NEXTDLGCTL, 0, 0);

    return; /* TRUE */

  case IDD_LOGIN:
    if (isblocking)
      return; /* TRUE */

    GetDlgItemText(hwnd, IDD_LOGIN_NAME, name, sizeof(name));
    trim(name);
    GetDlgItemText(hwnd, IDD_LOGIN_REALM, realm, sizeof(realm));
    trim(realm);
    GetDlgItemText(hwnd, IDD_LOGIN_PASSWORD, password, sizeof(password));
    SetDlgItemText(hwnd, IDD_LOGIN_PASSWORD, "");  /* nuke the password */
    trim(password);

#ifdef KRB4
    GetDlgItemText(hwnd, IDD_LOGIN_INSTANCE, instance, sizeof(instance));
    trim(instance);
#endif

    hcursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
    lifetime = cns_res.lifetime;
    start_blocking_hook(BLOCK_MAX_SEC);

#ifdef KRB4
    lifetime = (lifetime + 4) / 5;
    krc = krb_get_pw_in_tkt(name, instance, realm, "krbtgt", realm,
			    lifetime, password);
#endif

#ifdef KRB5
    principal = NULL;

    /*
     * convert the name + realm into a krb5 principal string and parse it into a principal
     */
    sprintf(menuitem, "%s@%s", name, realm);
    code = krb5_parse_name(k5_context, menuitem, &principal);
    if (code)
      goto errorpoint;

    /*
     * set the various ticket options.  First, initialize the structure, then set the ticket
     * to be forwardable if desired, and set the lifetime.
     */
    krb5_get_init_creds_opt_init(&opts);
    krb5_get_init_creds_opt_set_forwardable(&opts, forwardable);
    krb5_get_init_creds_opt_set_tkt_life(&opts, lifetime * 60);
    if (noaddresses) {
		krb5_get_init_creds_opt_set_address_list(&opts, NULL);
 	}

    /*
     * get the initial creds using the password and the options we set above
     */
    gd.hinstance = hinstance;
    gd.hwnd = hwnd;
    gd.id = ID_VARDLG;
    code = krb5_get_init_creds_password(k5_context, &creds, principal, password,
					gic_prompter, &gd, 0, NULL, &opts);
    if (code)
      goto errorpoint;

    /*
     * initialize the credential cache
     */
    code = krb5_cc_initialize(k5_context, k5_ccache, principal);
    if (code)
      goto errorpoint;

    /*
     * insert the principal into the cache
     */
    code = krb5_cc_store_cred(k5_context, k5_ccache, &creds);

  errorpoint:

    if (principal)
      krb5_free_principal(k5_context, principal);

    end_blocking_hook();
    SetCursor(hcursor);
    kwin_set_default_focus(hwnd);

    if (code) {
      if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY)
	MessageBox(hwnd, "Password incorrect", NULL,
		   MB_OK | MB_ICONEXCLAMATION);
      else
	com_err(NULL, code, "while logging in");
    }
#endif /* KRB5 */

#ifdef KRB4
    if (krc != KSUCCESS) {
      MessageBox(hwnd, krb_get_err_text(krc),	"",
		 MB_OK | MB_ICONEXCLAMATION);

      return; /* TRUE */
    }
#endif

    kwin_save_name(hwnd);
    alerted = FALSE;

    switch (action) {
    case LOGIN_AND_EXIT:
      SendMessage(hwnd, WM_COMMAND, GET_WM_COMMAND_MPS(IDM_EXIT, 0, 0));
      break;

    case LOGIN_AND_MINIMIZE:
      ShowWindow(hwnd, SW_MINIMIZE);
      break;
    }

    return; /* TRUE */

  case IDD_TICKET_DELETE:
    if (isblocking)
      return; /* TRUE */

#ifdef KRB4
    krc = dest_tkt();
    if (krc != KSUCCESS)
      MessageBox(hwnd, krb_get_err_text(krc),	"",
		 MB_OK | MB_ICONEXCLAMATION);
#endif

#ifdef KRB5
    code = k5_dest_tkt();
#endif

    kwin_set_default_focus(hwnd);
    alerted = FALSE;

    return; /* TRUE */

  case IDD_CHANGE_PASSWORD:
    if (isblocking)
      return; /* TRUE */
    password_dialog(hwnd);
    kwin_set_default_focus(hwnd);

    return; /* TRUE */

  case IDM_OPTIONS:
    if (isblocking)
      return; /* TRUE */
    opts_dialog(hwnd);

    return; /* TRUE */

  case IDM_HELP_INDEX:
    WinHelp(hwnd, KERBEROS_HLP, HELP_INDEX, 0);

    return; /* TRUE */

  case IDM_ABOUT:
    ticket_init_list(GetDlgItem(hwnd, IDD_TICKET_LIST));
    if (isblocking)
      return; /* TRUE */

#ifdef KRB4
    strcpy(copyright, "        Kerberos 4 for Windows ");
#endif
#ifdef KRB5
    strcpy(copyright, "        Kerberos V5 for Windows ");
#endif
#ifdef _WIN32
    strncat(copyright, "32-bit\n", sizeof(copyright) - 1 - strlen(copyright));
#else
    strncat(copyright, "16-bit\n", sizeof(copyright) - 1 - strlen(copyright));
#endif
    strncat(copyright, "\n                Version 1.12\n\n",
            sizeof(copyright) - 1 - strlen(copyright));
#ifdef ORGANIZATION
    strncat(copyright, "          For information, contact:\n",
	    sizeof(copyright) - 1 - strlen(copyright));
    strncat(copyright, ORGANIZATION, sizeof(copyright) - 1 - strlen(copyright));
#endif
    MessageBox(hwnd, copyright, KWIN_DIALOG_NAME, MB_OK);

    return; /* TRUE */
  }

  return; /* FALSE */
}
Ejemplo n.º 21
0
static ADS_STATUS ads_krb5_chg_password(const char *kdc_host,
					const char *principal,
					const char *oldpw, 
					const char *newpw, 
					int time_offset)
{
    ADS_STATUS aret;
    krb5_error_code ret;
    krb5_context context = NULL;
    krb5_principal princ;
    krb5_get_init_creds_opt opts;
    krb5_creds creds;
    char *chpw_princ = NULL, *password;
    const char *realm = NULL;

    initialize_krb5_error_table();
    ret = krb5_init_context(&context);
    if (ret) {
	DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret)));
	return ADS_ERROR_KRB5(ret);
    }

    if ((ret = smb_krb5_parse_name(context, principal,
                                    &princ))) {
	krb5_free_context(context);
	DEBUG(1,("Failed to parse %s (%s)\n", principal, error_message(ret)));
	return ADS_ERROR_KRB5(ret);
    }

    krb5_get_init_creds_opt_init(&opts);
    krb5_get_init_creds_opt_set_tkt_life(&opts, 5*60);
    krb5_get_init_creds_opt_set_renew_life(&opts, 0);
    krb5_get_init_creds_opt_set_forwardable(&opts, 0);
    krb5_get_init_creds_opt_set_proxiable(&opts, 0);

    realm = smb_krb5_principal_get_realm(context, princ);

    /* We have to obtain an INITIAL changepw ticket for changing password */
    if (asprintf(&chpw_princ, "kadmin/changepw@%s", realm) == -1) {
	krb5_free_context(context);
	DEBUG(1,("ads_krb5_chg_password: asprintf fail\n"));
	return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
    }

    password = SMB_STRDUP(oldpw);
    ret = krb5_get_init_creds_password(context, &creds, princ, password,
					   kerb_prompter, NULL, 
					   0, chpw_princ, &opts);
    SAFE_FREE(chpw_princ);
    SAFE_FREE(password);

    if (ret) {
      if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY)
	DEBUG(1,("Password incorrect while getting initial ticket"));
      else
	DEBUG(1,("krb5_get_init_creds_password failed (%s)\n", error_message(ret)));

	krb5_free_principal(context, princ);
	krb5_free_context(context);
	return ADS_ERROR_KRB5(ret);
    }

    aret = do_krb5_kpasswd_request(context, kdc_host,
				   KRB5_KPASSWD_VERS_CHANGEPW,
				   &creds, principal, newpw);

    krb5_free_principal(context, princ);
    krb5_free_context(context);

    return aret;
}
Ejemplo n.º 22
0
/* returns boolean */
static int
k5_kinit(struct k_opts *opts, struct k5_data *k5, struct user_info *u_info)
{
    char *doing;
    int notix = 1;
    krb5_keytab keytab = 0;
    krb5_creds my_creds;
    krb5_error_code code = 0;
    krb5_get_init_creds_opt options;
    krb5_address **addresses;

    krb5_get_init_creds_opt_init(&options);
    g_memset(&my_creds, 0, sizeof(my_creds));

    /*
      From this point on, we can goto cleanup because my_creds is
      initialized.
    */
    if (opts->lifetime)
    {
        krb5_get_init_creds_opt_set_tkt_life(&options, opts->lifetime);
    }

    if (opts->rlife)
    {
        krb5_get_init_creds_opt_set_renew_life(&options, opts->rlife);
    }

    if (opts->forwardable)
    {
        krb5_get_init_creds_opt_set_forwardable(&options, 1);
    }

    if (opts->not_forwardable)
    {
        krb5_get_init_creds_opt_set_forwardable(&options, 0);
    }

    if (opts->proxiable)
    {
        krb5_get_init_creds_opt_set_proxiable(&options, 1);
    }

    if (opts->not_proxiable)
    {
        krb5_get_init_creds_opt_set_proxiable(&options, 0);
    }

    if (opts->addresses)
    {
        addresses = NULL;
        code = krb5_os_localaddr(k5->ctx, &addresses);

        if (code != 0)
        {
            g_printf("krb5_os_localaddr failed in k5_kinit\n");
            goto cleanup;
        }

        krb5_get_init_creds_opt_set_address_list(&options, addresses);
    }

    if (opts->no_addresses)
    {
        krb5_get_init_creds_opt_set_address_list(&options, NULL);
    }

    if ((opts->action == INIT_KT) && opts->keytab_name)
    {
        code = krb5_kt_resolve(k5->ctx, opts->keytab_name, &keytab);

        if (code != 0)
        {
            g_printf("krb5_kt_resolve failed in k5_kinit\n");
            goto cleanup;
        }
    }

    switch (opts->action)
    {
        case INIT_PW:
            code = krb5_get_init_creds_password(k5->ctx, &my_creds, k5->me,
                                                0, kinit_prompter, u_info,
                                                opts->starttime,
                                                opts->service_name,
                                                &options);
            break;
        case INIT_KT:
            code = krb5_get_init_creds_keytab(k5->ctx, &my_creds, k5->me,
                                              keytab,
                                              opts->starttime,
                                              opts->service_name,
                                              &options);
            break;
        case VALIDATE:
            code = krb5_get_validated_creds(k5->ctx, &my_creds, k5->me, k5->cc,
                                            opts->service_name);
            break;
        case RENEW:
            code = krb5_get_renewed_creds(k5->ctx, &my_creds, k5->me, k5->cc,
                                          opts->service_name);
            break;
    }

    if (code != 0)
    {
        doing = 0;

        switch (opts->action)
        {
            case INIT_PW:
            case INIT_KT:
                doing = "getting initial credentials";
                break;
            case VALIDATE:
                doing = "validating credentials";
                break;
            case RENEW:
                doing = "renewing credentials";
                break;
        }

        if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY)
        {
            g_printf("sesman: Password incorrect while %s in k5_kinit\n", doing);
        }
        else
        {
            g_printf("sesman: error while %s in k5_kinit\n", doing);
        }

        goto cleanup;
    }

    if (!opts->lifetime)
    {
        /* We need to figure out what lifetime to use for Kerberos 4. */
        opts->lifetime = my_creds.times.endtime - my_creds.times.authtime;
    }

    code = krb5_cc_initialize(k5->ctx, k5->cc, k5->me);

    if (code != 0)
    {
        g_printf("krb5_cc_initialize failed in k5_kinit\n");
        goto cleanup;
    }

    code = krb5_cc_store_cred(k5->ctx, k5->cc, &my_creds);

    if (code != 0)
    {
        g_printf("krb5_cc_store_cred failed in k5_kinit\n");
        goto cleanup;
    }

    notix = 0;

cleanup:

    if (my_creds.client == k5->me)
    {
        my_creds.client = 0;
    }

    krb5_free_cred_contents(k5->ctx, &my_creds);

    if (keytab)
    {
        krb5_kt_close(k5->ctx, keytab);
    }

    return notix ? 0 : 1;
}
Ejemplo n.º 23
0
static
DWORD
IDMKrbRenewCredentials(
    PIDM_KRB_CONTEXT pKrbContext
    )
{
    DWORD   dwError = 0;
    DWORD   dwCleanupError = 0;
    BOOLEAN bLocked = FALSE;
    BOOLEAN bRefreshCreds = FALSE;
    krb5_context   pCtx   = NULL;
    PSTR           pszPrincipal = NULL;
    krb5_principal pPrincipal = NULL;
    krb5_keytab    ktid   = 0;
    krb5_ccache    pCache = NULL;
    krb5_creds     creds = {0};

    IDM_RWMUTEX_LOCK_SHARED(&pKrbContext->mutex_rw, bLocked, dwError);
    BAIL_ON_ERROR(dwError);

    if (!pKrbContext->expiryTime)
    {
        bRefreshCreds = TRUE;
    }
    else
    {
        krb5_timestamp now = time(NULL);

        if (now >= pKrbContext->expiryTime)
        {
            bRefreshCreds = TRUE;
        }
        else
        {
            double threshold = (30 * 60); // 30 minutes
            double interval = difftime(pKrbContext->expiryTime, now);

            if (interval <= threshold)
            {
                bRefreshCreds = TRUE;
            }
        }
    }

    if (bRefreshCreds)
    {
        krb5_error_code errKrb = 0;
        krb5_deltat    startTime = 0;
        PSTR pszServiceName = NULL;
        krb5_get_init_creds_opt options = {0};
        krb5_timestamp origExpiryTime = pKrbContext->expiryTime;

        IDM_RWMUTEX_UNLOCK(&pKrbContext->mutex_rw, bLocked, dwError);
        BAIL_ON_ERROR(dwError);

        dwError = IDMKrbGetPrincipal(
                      pKrbContext->pszAccount,
                      pKrbContext->pszDomain,
                      &pszPrincipal);
        BAIL_ON_ERROR(dwError);

        errKrb = krb5_init_context(&pCtx);
        BAIL_ON_KERBEROS_ERROR(NULL, errKrb, dwError);

        errKrb = krb5_parse_name(pCtx, pszPrincipal, &pPrincipal);
        BAIL_ON_KERBEROS_ERROR(NULL, errKrb, dwError);

        errKrb = krb5_kt_default(pCtx, &ktid);
        BAIL_ON_KERBEROS_ERROR(NULL, errKrb, dwError);

        krb5_get_init_creds_opt_init(&options);
        krb5_get_init_creds_opt_set_forwardable(&options, TRUE);

        errKrb = krb5_get_init_creds_keytab(
                    pCtx,
                    &creds,
                    pPrincipal,
                    ktid,
                    startTime,
                    pszServiceName,
                    &options);
        BAIL_ON_KERBEROS_ERROR(NULL, errKrb, dwError);

        IDM_RWMUTEX_LOCK_EXCLUSIVE(&pKrbContext->mutex_rw, bLocked, dwError);
        BAIL_ON_ERROR(dwError);

        if (pKrbContext->expiryTime <= origExpiryTime)
        {
            errKrb = krb5_cc_resolve(pCtx, pKrbContext->pszCachePath, &pCache);
            BAIL_ON_KERBEROS_ERROR(NULL, errKrb, dwError);

            errKrb = krb5_cc_initialize(pCtx, pCache, pPrincipal);
            BAIL_ON_KERBEROS_ERROR(NULL, errKrb, dwError);

            errKrb = krb5_cc_store_cred(pCtx, pCache, &creds);
            BAIL_ON_KERBEROS_ERROR(NULL, errKrb, dwError);

            pKrbContext->expiryTime = creds.times.endtime;
        }
    }

cleanup:

    IDM_RWMUTEX_UNLOCK(&pKrbContext->mutex_rw, bLocked, dwCleanupError);

    if (pCtx)
    {
        if (ktid)
        {
            krb5_kt_close(pCtx, ktid);
            ktid = 0;
        }
        if (pPrincipal)
        {
            if (creds.client == pPrincipal)
            {
                creds.client = NULL;
            }

            krb5_free_principal(pCtx, pPrincipal);
        }

        krb5_free_cred_contents(pCtx, &creds);

        if (pCache)
        {
            krb5_cc_close(pCtx, pCache);
        }

        krb5_free_context(pCtx);
    }

    IDM_SAFE_FREE_MEMORY(pszPrincipal);

    if(!dwError)
    {
        dwError = dwCleanupError;
    }
    return dwError;

error:

    goto cleanup;
}
Ejemplo n.º 24
0
static krb5_error_code
change_pw(krb5_context context,
	  kcm_ccache ccache,
	  char *cpn,
	  char *newpw)
{
    krb5_error_code ret;
    krb5_creds cpw_cred;
    int result_code;
    krb5_data result_code_string;
    krb5_data result_string;
    krb5_get_init_creds_opt options;

    memset(&cpw_cred, 0, sizeof(cpw_cred));

    krb5_get_init_creds_opt_init(&options);
    krb5_get_init_creds_opt_set_tkt_life(&options, 60);
    krb5_get_init_creds_opt_set_forwardable(&options, FALSE);
    krb5_get_init_creds_opt_set_proxiable(&options, FALSE);

    krb5_data_zero(&result_code_string);
    krb5_data_zero(&result_string);

    ret = krb5_get_init_creds_keytab(context,
				     &cpw_cred,
				     ccache->client,
				     ccache->key.keytab,
				     0,
				     "kadmin/changepw",
				     &options);
    if (ret) {
	kcm_log(0, "Failed to acquire password change credentials "
		"for principal %s: %s", 
		cpn, krb5_get_err_text(context, ret));
	goto out;
    }

    ret = krb5_set_password(context,
			    &cpw_cred,
			    newpw,
			    ccache->client,
			    &result_code,
			    &result_code_string,
			    &result_string);
    if (ret) {
	kcm_log(0, "Failed to change password for principal %s: %s",
		cpn, krb5_get_err_text(context, ret));
	goto out;
    }

    if (result_code) {
	kcm_log(0, "Failed to change password for principal %s: %.*s",
		cpn,
		(int)result_string.length,
		result_string.length > 0 ? (char *)result_string.data : "");
	goto out;
    }

out:
    krb5_data_free(&result_string);
    krb5_data_free(&result_code_string);
    krb5_free_cred_contents(context, &cpw_cred);

    return ret;
}
Ejemplo n.º 25
0
char *					/* R: allocated response string */
auth_krb5 (
  /* PARAMETERS */
  const char *user,			/* I: plaintext authenticator */
  const char *password,			/* I: plaintext password */
  const char *service,			/* I: service authenticating to */
  const char *realm			/* I: user's realm */
  /* END PARAMETERS */
  )
{
    /* VARIABLES */
    krb5_context context;
    krb5_ccache ccache = NULL;
    krb5_principal auth_user;
    krb5_creds creds;
    krb5_get_init_creds_opt opts;
    char * result;
    char tfname[2048];
    char principalbuf[2048];
    krb5_error_code code;
    /* END VARIABLES */

    if (!user|| !password) {
	syslog(LOG_ERR, "auth_krb5: NULL password or username?");
	return strdup("NO saslauthd internal error");
    }

    if (krb5_init_context(&context)) {
	syslog(LOG_ERR, "auth_krb5: krb5_init_context");
	return strdup("NO saslauthd internal error");
    }

    if (form_principal_name(user, service, realm, principalbuf, sizeof (principalbuf))) {
	syslog(LOG_ERR, "auth_krb5: form_principal_name");
	return strdup("NO saslauthd principal name error");
    }

    if (krb5_parse_name (context, principalbuf, &auth_user)) {
	krb5_free_context(context);
	syslog(LOG_ERR, "auth_krb5: krb5_parse_name");
	return strdup("NO saslauthd internal error");
    }
    
    if (krbtf_name(tfname, sizeof (tfname)) != 0) {
	syslog(LOG_ERR, "auth_krb5: could not generate ticket file name");
	return strdup("NO saslauthd internal error");
    }

    if (krb5_cc_resolve(context, tfname, &ccache)) {
	krb5_free_principal(context, auth_user);
	krb5_free_context(context);
	syslog(LOG_ERR, "auth_krb5: krb5_cc_resolve");
	return strdup("NO saslauthd internal error");
    }
    
    if (krb5_cc_initialize (context, ccache, auth_user)) {
	krb5_free_principal(context, auth_user);
	krb5_free_context(context);
	syslog(LOG_ERR, "auth_krb5: krb5_cc_initialize");
	return strdup("NO saslauthd internal error");
    }
    
    krb5_get_init_creds_opt_init(&opts);
    /* 15 min should be more than enough */
    krb5_get_init_creds_opt_set_tkt_life(&opts, 900); 
    if ((code = krb5_get_init_creds_password(context, &creds, 
                                             auth_user, password, NULL, NULL, 
                                             0, NULL, &opts))) {
	krb5_cc_destroy(context, ccache);
	krb5_free_principal(context, auth_user);
	krb5_free_context(context);
	syslog(LOG_ERR, "auth_krb5: krb5_get_init_creds_password: %d", code);
	return strdup("NO saslauthd internal error");
    }
    
    /* at this point we should have a TGT. Let's make sure it is valid */
    if (krb5_cc_store_cred(context, ccache, &creds)) {
	krb5_free_principal(context, auth_user);
	krb5_cc_destroy(context, ccache);
	krb5_free_context(context);
	syslog(LOG_ERR, "auth_krb5: krb5_cc_store_cred");
	return strdup("NO saslauthd internal error");
    }
    
    if (!k5support_verify_tgt(context, ccache)) {
	syslog(LOG_ERR, "auth_krb5: k5support_verify_tgt");
	result = strdup("NO saslauthd internal error");
	goto fini;
    }
    
    /* 
     * fall through -- user is valid beyond this point  
     */
    
    result = strdup("OK");
 fini:
/* destroy any tickets we had */
    krb5_free_cred_contents(context, &creds);
    krb5_free_principal(context, auth_user);
    krb5_cc_destroy(context, ccache);
    krb5_free_context(context);

    return result;
}
Ejemplo n.º 26
0
/*
 * Obtain credentials via a key in the keytab given
 * a keytab handle and a gssd_k5_kt_princ structure.
 * Checks to see if current credentials are expired,
 * if not, uses the keytab to obtain new credentials.
 *
 * Returns:
 *	0 => success (or credentials have not expired)
 *	nonzero => error
 */
static int gssd_get_single_krb5_cred(krb5_context context, krb5_keytab kt,
				     struct gssd_k5_kt_princ *ple, int nocache)
{
#if HAVE_KRB5_GET_INIT_CREDS_OPT_SET_ADDRESSLESS
	krb5_get_init_creds_opt *init_opts = NULL;
#else
	krb5_get_init_creds_opt options;
#endif
	krb5_get_init_creds_opt *opts;
	krb5_creds my_creds;
	krb5_ccache ccache = NULL;
	char kt_name[BUFSIZ];
	char cc_name[BUFSIZ];
	int code;
	time_t now = time(0);
	char *cache_type;
	char *pname = NULL;
	char *k5err = NULL;

	memset(&my_creds, 0, sizeof(my_creds));

	if (ple->ccname && ple->endtime > now && !nocache) {
		printerr(2, "INFO: Credentials in CC '%s' are good until %d\n",
			 ple->ccname, ple->endtime);
		code = 0;
		goto out;
	}

	code = krb5_kt_get_name(context, kt, kt_name, BUFSIZ);
	if (code != 0) {
		printerr(0,
			 "ERROR: Unable to get keytab name in "
			 "gssd_get_single_krb5_cred\n");
		goto out;
	}

	if ((krb5_unparse_name(context, ple->princ, &pname)))
		pname = NULL;

#if HAVE_KRB5_GET_INIT_CREDS_OPT_SET_ADDRESSLESS
	code = krb5_get_init_creds_opt_alloc(context, &init_opts);
	if (code) {
		k5err = gssd_k5_err_msg(context, code);
		printerr(0, "ERROR: %s allocating gic options\n", k5err);
		goto out;
	}
	if (krb5_get_init_creds_opt_set_addressless(context, init_opts, 1))
		printerr(1,
			 "WARNING: Unable to set option for addressless "
			 "tickets.  May have problems behind a NAT.\n");
#ifdef TEST_SHORT_LIFETIME
	/* set a short lifetime (for debugging only!) */
	printerr(0, "WARNING: Using (debug) short machine cred lifetime!\n");
	krb5_get_init_creds_opt_set_tkt_life(init_opts, 5 * 60);
#endif
	opts = init_opts;

#else /* HAVE_KRB5_GET_INIT_CREDS_OPT_SET_ADDRESSLESS */

	krb5_get_init_creds_opt_init(&options);
	krb5_get_init_creds_opt_set_address_list(&options, NULL);
#ifdef TEST_SHORT_LIFETIME
	/* set a short lifetime (for debugging only!) */
	printerr(0, "WARNING: Using (debug) short machine cred lifetime!\n");
	krb5_get_init_creds_opt_set_tkt_life(&options, 5 * 60);
#endif
	opts = &options;
#endif

	code = krb5_get_init_creds_keytab(context, &my_creds,
					  ple->princ, kt, 0,
					  NULL, opts);
	if (code != 0) {
		k5err = gssd_k5_err_msg(context, code);
		printerr(1,
			 "WARNING: %s while getting initial ticket for "
			 "principal '%s' using keytab '%s'\n", k5err,
			 pname ? pname : "<unparsable>", kt_name);
		goto out;
	}

	/*
	 * Initialize cache file which we're going to be using
	 */

	if (use_memcache)
		cache_type = "MEMORY";
	else
		cache_type = "FILE";
	snprintf(cc_name, sizeof(cc_name), "%s:%s/%s%s_%s", cache_type,
		 ccachesearch[0], GSSD_DEFAULT_CRED_PREFIX,
		 GSSD_DEFAULT_MACHINE_CRED_SUFFIX, ple->realm);
	ple->endtime = my_creds.times.endtime;
	if (ple->ccname != NULL)
		gsh_free(ple->ccname);
	ple->ccname = gsh_strdup(cc_name);
	if (ple->ccname == NULL) {
		printerr(0,
			 "ERROR: no storage to duplicate credentials "
			 "cache name '%s'\n", cc_name);
		code = ENOMEM;
		goto out;
	}
	code = krb5_cc_resolve(context, cc_name, &ccache);
	if (code != 0) {
		k5err = gssd_k5_err_msg(context, code);
		printerr(0, "ERROR: %s while opening credential cache '%s'\n",
			 k5err, cc_name);
		goto out;
	}
	code = krb5_cc_initialize(context, ccache, ple->princ);
	if (code != 0) {
		k5err = gssd_k5_err_msg(context, code);
		printerr(0,
			 "ERROR: %s while initializing credential "
			 "cache '%s'\n", k5err, cc_name);
	}
	code = krb5_cc_store_cred(context, ccache, &my_creds);
	if (code != 0) {
		k5err = gssd_k5_err_msg(context, code);
		printerr(0, "ERROR: %s while storing credentials in '%s'\n",
			 k5err, cc_name);
		goto out;
	}
	/* if we get this far, let gss mech know */
	gssd_set_krb5_ccache_name(cc_name);
	code = 0;
	printerr(2,
		 "Successfully obtained machine credentials for "
		 "principal '%s' stored in ccache '%s'\n", pname, cc_name);
 out:
#if HAVE_KRB5_GET_INIT_CREDS_OPT_SET_ADDRESSLESS
	if (init_opts)
		krb5_get_init_creds_opt_free(context, init_opts);
#endif
	if (pname)
		k5_free_unparsed_name(context, pname);
	if (ccache)
		krb5_cc_close(context, ccache);
	krb5_free_cred_contents(context, &my_creds);
	gsh_free(k5err);
	return code;
}
Ejemplo n.º 27
0
static int
unenroll_host(const char *server, const char *hostname, const char *ktname, int quiet)
{
    int rval = 0;
    int ret;
    char *ipaserver = NULL;
    char *host = NULL;
    struct utsname uinfo;
    char *principal = NULL;
    char *realm = NULL;

    krb5_context krbctx = NULL;
    krb5_keytab keytab = NULL;
    krb5_ccache ccache = NULL;
    krb5_principal princ = NULL;
    krb5_error_code krberr;
    krb5_creds creds;
    krb5_get_init_creds_opt gicopts;
    char tgs[LINE_MAX];

    xmlrpc_env env;
    xmlrpc_value * argArrayP = NULL;
    xmlrpc_value * paramArrayP = NULL;
    xmlrpc_value * paramP = NULL;
    xmlrpc_value * resultP = NULL;
    xmlrpc_server_info * serverInfoP = NULL;
    xmlrpc_value *princP = NULL;
    char * url = NULL;
    char * user_agent = NULL;

    if (server) {
        ipaserver = strdup(server);
    } else {
        char * conf_data = read_config_file(IPA_CONFIG);
        if ((ipaserver = getIPAserver(conf_data)) == NULL) {
            if (!quiet)
                fprintf(stderr, _("Unable to determine IPA server from %s\n"),
                        IPA_CONFIG);
            exit(1);
        }
        free(conf_data);
    }

    if (NULL == hostname) {
        uname(&uinfo);
        host = strdup(uinfo.nodename);
    } else {
        host = strdup(hostname);
    }

    if (NULL == strstr(host, ".")) {
        if (!quiet)
            fprintf(stderr, _("The hostname must be fully-qualified: %s\n"),
                    host);
        rval = 16;
        goto cleanup;
    }

    krberr = krb5_init_context(&krbctx);
    if (krberr) {
        if (!quiet)
            fprintf(stderr, _("Unable to join host: "
                              "Kerberos context initialization failed\n"));
        rval = 1;
        goto cleanup;
    }
    krberr = krb5_kt_resolve(krbctx, ktname, &keytab);
    if (krberr != 0) {
        if (!quiet)
            fprintf(stderr, _("Error resolving keytab: %s.\n"),
                error_message(krberr));
        rval = 7;
        goto cleanup;
    }

    krberr = krb5_get_default_realm(krbctx, &realm);
    if (krberr != 0) {
        if (!quiet)
            fprintf(stderr, _("Error getting default Kerberos realm: %s.\n"),
                error_message(krberr));
        rval = 21;
        goto cleanup;
    }

    ret = asprintf(&principal, "host/%s@%s", host,  realm);
    if (ret == -1)
    {
        if (!quiet)
            fprintf(stderr, _("Out of memory!\n"));
        rval = 3;
        goto cleanup;
    }

    krberr = krb5_parse_name(krbctx, principal, &princ);
    if (krberr != 0) {
        if (!quiet)
            fprintf(stderr, _("Error parsing \"%1$s\": %2$s.\n"),
                            principal, error_message(krberr));
        return krberr;
    }
    strcpy(tgs, KRB5_TGS_NAME);
    snprintf(tgs + strlen(tgs), sizeof(tgs) - strlen(tgs), "/%.*s",
             (krb5_princ_realm(krbctx, princ))->length,
             (krb5_princ_realm(krbctx, princ))->data);
    snprintf(tgs + strlen(tgs), sizeof(tgs) - strlen(tgs), "@%.*s",
             (krb5_princ_realm(krbctx, princ))->length,
             (krb5_princ_realm(krbctx, princ))->data);
    memset(&creds, 0, sizeof(creds));
    krb5_get_init_creds_opt_init(&gicopts);
    krb5_get_init_creds_opt_set_forwardable(&gicopts, 1);
    krberr = krb5_get_init_creds_keytab(krbctx, &creds, princ, keytab,
                                      0, tgs, &gicopts);
    if (krberr != 0) {
        if (!quiet)
            fprintf(stderr, _("Error obtaining initial credentials: %s.\n"),
                    error_message(krberr));
        return krberr;
    }

    krberr = krb5_cc_resolve(krbctx, "MEMORY:ipa-join", &ccache);
    if (krberr == 0) {
        krberr = krb5_cc_initialize(krbctx, ccache, creds.client);
    } else {
        if (!quiet)
            fprintf(stderr,
                    _("Unable to generate Kerberos Credential Cache\n"));
        rval = 19;
        goto cleanup;
    }
    krberr = krb5_cc_store_cred(krbctx, ccache, &creds);
    if (krberr != 0) {
        if (!quiet)
            fprintf(stderr,
                    _("Error storing creds in credential cache: %s.\n"),
                    error_message(krberr));
        return krberr;
    }
    krb5_cc_close(krbctx, ccache);
    ccache = NULL;
    putenv("KRB5CCNAME=MEMORY:ipa-join");

    /* Start up our XML-RPC client library. */
    xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION);

    xmlrpc_env_init(&env);

    xmlrpc_client_setup_global_const(&env);

#if 1
    ret = asprintf(&url, "https://%s:443/ipa/xml", ipaserver);
#else
    ret = asprintf(&url, "http://%s:8888/", ipaserver);
#endif
    if (ret == -1)
    {
        if (!quiet)
            fprintf(stderr, _("Out of memory!\n"));
        rval = 3;
        goto cleanup;
    }
    serverInfoP = xmlrpc_server_info_new(&env, url);

    argArrayP = xmlrpc_array_new(&env);
    paramArrayP = xmlrpc_array_new(&env);

    paramP = xmlrpc_string_new(&env, host);
    xmlrpc_array_append_item(&env, argArrayP, paramP);
    xmlrpc_array_append_item(&env, paramArrayP, argArrayP);
    xmlrpc_DECREF(paramP);

    if ((user_agent = set_user_agent(ipaserver)) == NULL) {
        rval = 3;
        goto cleanup;
    }
    callRPC(user_agent, &env, serverInfoP, "host_disable", paramArrayP, &resultP);
    if (handle_fault(&env)) {
        rval = 17;
        goto cleanup;
    }

    xmlrpc_struct_find_value(&env, resultP, "result", &princP);
    if (princP) {
        xmlrpc_bool result;

        xmlrpc_read_bool(&env, princP, &result);
        if (result == 1) {
            if (!quiet)
                fprintf(stderr, _("Unenrollment successful.\n"));
        } else {
            if (!quiet)
                fprintf(stderr, _("Unenrollment failed.\n"));
        }

        xmlrpc_DECREF(princP);
    } else {
        fprintf(stderr, _("result not found in XML-RPC response\n"));
        rval = 20;
        goto cleanup;
    }

cleanup:

    free(user_agent);
    if (keytab) krb5_kt_close(krbctx, keytab);
    free((char *)principal);
    free((char *)ipaserver);
    if (princ) krb5_free_principal(krbctx, princ);
    if (ccache) krb5_cc_close(krbctx, ccache);
    if (krbctx) krb5_free_context(krbctx);

    free(url);
    xmlrpc_env_clean(&env);
    xmlrpc_client_cleanup();

    return rval;
}