예제 #1
0
OM_uint32 KRB5_CALLCONV
gss_pname_to_uid(OM_uint32 *minor,
                 const gss_name_t name,
                 const gss_OID mech_type,
                 uid_t *uidOut)
{
    OM_uint32 major = GSS_S_UNAVAILABLE, tmpminor;
#ifndef NO_PASSWORD
    gss_buffer_desc localname;
    char pwbuf[BUFSIZ];
    char *localuser = NULL;
    struct passwd *pwd = NULL;
    struct passwd pw;
    int code = 0;

    localname.value = NULL;
    major = gss_localname(minor, name, mech_type, &localname);
    if (!GSS_ERROR(major) && localname.value) {
        localuser = malloc(localname.length + 1);
        if (localuser == NULL)
            code = ENOMEM;
        if (code == 0) {
            memcpy(localuser, localname.value, localname.length);
            localuser[localname.length] = '\0';
            code = k5_getpwnam_r(localuser, &pw, pwbuf, sizeof(pwbuf), &pwd);
        }
        if ((code == 0) && pwd)
            *uidOut = pwd->pw_uid;
        else
            major = GSS_S_FAILURE;
    }
    free(localuser);
    if (localname.value)
        gss_release_buffer(&tmpminor, &localname);
#endif /*NO_PASSWORD*/
    return major;
}
예제 #2
0
파일: kuserok.c 프로젝트: Brainiarc7/pbis
/*
 * Determine whether principal is authorized to log in as luser according to
 * the user's k5login file.  Return ACCEPT if the k5login file authorizes the
 * principal, PASS if the k5login file does not exist, or REJECT if the k5login
 * file exists but does not authorize the principal.  If k5login files are
 * configured to be non-authoritative, pass instead of rejecting.
 */
static enum result
k5login_ok(krb5_context context, krb5_principal principal, const char *luser)
{
    int authoritative = TRUE, gobble;
    enum result result = REJECT;
    char *filename = NULL, *princname = NULL;
    char *newline, linebuf[BUFSIZ], pwbuf[BUFSIZ];
    struct stat sbuf;
    struct passwd pwx, *pwd;
    FILE *fp = NULL;

    if (profile_get_boolean(context->profile, KRB5_CONF_LIBDEFAULTS,
                            KRB5_CONF_K5LOGIN_AUTHORITATIVE, NULL, TRUE,
                            &authoritative) != 0)
        goto cleanup;

    /* Get the local user's homedir and uid. */
    if (k5_getpwnam_r(luser, &pwx, pwbuf, sizeof(pwbuf), &pwd) != 0)
        goto cleanup;

    if (get_k5login_filename(context, luser, pwd->pw_dir, &filename) != 0)
        goto cleanup;

    if (access(filename, F_OK) != 0) {
        result = PASS;
        goto cleanup;
    }

    if (krb5_unparse_name(context, principal, &princname) != 0)
        goto cleanup;

    fp = fopen(filename, "r");
    if (fp == NULL)
        goto cleanup;
    set_cloexec_file(fp);

    /* For security reasons, the .k5login file must be owned either by
     * the user or by root. */
    if (fstat(fileno(fp), &sbuf))
        goto cleanup;
    if (sbuf.st_uid != pwd->pw_uid && !FILE_OWNER_OK(sbuf.st_uid))
        goto cleanup;

    /* Check each line. */
    while (result != ACCEPT && (fgets(linebuf, sizeof(linebuf), fp) != NULL)) {
        newline = strrchr(linebuf, '\n');
        if (newline != NULL)
            *newline = '\0';
        if (strcmp(linebuf, princname) == 0)
            result = ACCEPT;
        /* Clean up the rest of the line if necessary. */
        if (newline == NULL)
            while (((gobble = getc(fp)) != EOF) && gobble != '\n');
    }

cleanup:
    free(princname);
    free(filename);
    if (fp != NULL)
        fclose(fp);
    /* If k5login files are non-authoritative, never reject. */
    return (!authoritative && result == REJECT) ? PASS : result;
}
예제 #3
0
krb5_boolean KRB5_CALLCONV
krb5_kuserok(krb5_context context, krb5_principal principal, const char *luser)
{
    struct stat sbuf;
    struct passwd *pwd;
    char pbuf[MAXPATHLEN];
    krb5_boolean isok = FALSE;
    FILE *fp;
    char kuser[MAX_USERNAME];
    char *princname;
    char linebuf[BUFSIZ];
    char *newline;
    int gobble;

    /* no account => no access */
    char pwbuf[BUFSIZ];
    struct passwd pwx;
    if (k5_getpwnam_r(luser, &pwx, pwbuf, sizeof(pwbuf), &pwd) != 0)
	return(FALSE);
    (void) strncpy(pbuf, pwd->pw_dir, sizeof(pbuf) - 1);
    pbuf[sizeof(pbuf) - 1] = '\0';
    (void) strncat(pbuf, "/.k5login", sizeof(pbuf) - 1 - strlen(pbuf));

    if (access(pbuf, F_OK)) {	 /* not accessible */
	/*
	 * if he's trying to log in as himself, and there is no .k5login file,
	 * let him.  To find out, call
	 * krb5_aname_to_localname to convert the principal to a name
	 * which we can string compare. 
	 */
	if (!(krb5_aname_to_localname(context, principal,
				      sizeof(kuser), kuser))
	    && (strcmp(kuser, luser) == 0)) {
	    return(TRUE);
	}
    }
    if (krb5_unparse_name(context, principal, &princname))
	return(FALSE);			/* no hope of matching */

    /* open ~/.k5login */
    if ((fp = fopen(pbuf, "r")) == NULL) {
	free(princname);
	return(FALSE);
    }
    set_cloexec_file(fp);
    /*
     * For security reasons, the .k5login file must be owned either by
     * the user himself, or by root.  Otherwise, don't grant access.
     */
    if (fstat(fileno(fp), &sbuf)) {
	fclose(fp);
	free(princname);
	return(FALSE);
    }
    if (sbuf.st_uid != pwd->pw_uid && !FILE_OWNER_OK(sbuf.st_uid)) {
	fclose(fp);
	free(princname);
	return(FALSE);
    }

    /* check each line */
    while (!isok && (fgets(linebuf, BUFSIZ, fp) != NULL)) {
	/* null-terminate the input string */
	linebuf[BUFSIZ-1] = '\0';
	newline = NULL;
	/* nuke the newline if it exists */
	if ((newline = strchr(linebuf, '\n')))
	    *newline = '\0';
	if (!strcmp(linebuf, princname)) {
	    isok = TRUE;
	    continue;
	}
	/* clean up the rest of the line if necessary */
	if (!newline)
	    while (((gobble = getc(fp)) != EOF) && gobble != '\n');
    }
    free(princname);
    fclose(fp);
    return(isok);
}
예제 #4
0
static OM_uint32
attr_pname_to_uid(OM_uint32 *minor,
                  const gss_mechanism mech,
                  const gss_name_t mech_name,
                  uid_t *uidp)
{
    OM_uint32 major = GSS_S_UNAVAILABLE;
#ifndef NO_PASSWORD
    OM_uint32 tmpMinor;
    int more = -1;

    if (mech->gss_get_name_attribute == NULL)
        return GSS_S_UNAVAILABLE;

    while (more != 0) {
        gss_buffer_desc value;
        gss_buffer_desc display_value;
        int authenticated = 0, complete = 0, code;
        char pwbuf[BUFSIZ];
        struct passwd pw, *pwd;
        char *localLoginUser;

        major = mech->gss_get_name_attribute(minor,
                                             mech_name,
                                             GSS_C_ATTR_LOCAL_LOGIN_USER,
                                             &authenticated,
                                             &complete,
                                             &value,
                                             &display_value,
                                             &more);
        if (GSS_ERROR(major)) {
            map_error(minor, mech);
            break;
        }

        localLoginUser = malloc(value.length + 1);
        if (localLoginUser == NULL) {
            major = GSS_S_FAILURE;
            *minor = ENOMEM;
            break;
        }

        memcpy(localLoginUser, value.value, value.length);
        localLoginUser[value.length] = '\0';

        code = k5_getpwnam_r(localLoginUser, &pw, pwbuf, sizeof(pwbuf), &pwd);

        free(localLoginUser);
        gss_release_buffer(&tmpMinor, &value);
        gss_release_buffer(&tmpMinor, &display_value);

        if (code == 0 && pwd != NULL) {
            *uidp = pwd->pw_uid;
            major = GSS_S_COMPLETE;
            *minor = 0;
            break;
        } else
            major = GSS_S_UNAVAILABLE;
    }
#endif /* !NO_PASSWORD */

    return major;
}