Beispiel #1
0
/*
 * Returns 0 if ok, -1 if not ok.
 */
static
int
__ivaliduser(FILE *hostf, unsigned raddr, const char *luser,
             const char *ruser)
{
    char *user, *p;
    int ch;
    char buf[MaxHostNameLen + 128];		/* host + login */
    char hname[MaxHostNameLen];
    struct hostent *hp;
    /* Presumed guilty until proven innocent. */
    int userok = 0, hostok = 0;
#ifdef HAVE_YP_GET_DEFAULT_DOMAIN
    char *ypdomain;

    if (yp_get_default_domain(&ypdomain))
        ypdomain = NULL;
#else
#define	ypdomain NULL
#endif
    /* We need to get the damn hostname back for netgroup matching. */
    if ((hp = gethostbyaddr((char *)&raddr,
                            sizeof(u_long),
                            AF_INET)) == NULL)
        return (-1);
    strlcpy(hname, hp->h_name, sizeof(hname));

    while (fgets(buf, sizeof(buf), hostf)) {
        p = buf;
        /* Skip lines that are too long. */
        if (strchr(p, '\n') == NULL) {
            while ((ch = getc(hostf)) != '\n' && ch != EOF);
            continue;
        }
        if (*p == '\n' || *p == '#') {
            /* comment... */
            continue;
        }
        while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
            if (isupper((unsigned char)*p))
                *p = tolower((unsigned char)*p);
            p++;
        }
        if (*p == ' ' || *p == '\t') {
            *p++ = '\0';
            while (*p == ' ' || *p == '\t')
                p++;
            user = p;
            while (*p != '\n' && *p != ' ' &&
                    *p != '\t' && *p != '\0')
                p++;
        } else
            user = p;
        *p = '\0';
        /*
         * Do +/- and +@/-@ checking. This looks really nasty,
         * but it matches SunOS's behavior so far as I can tell.
         */
        switch(buf[0]) {
        case '+':
            if (!buf[1]) {     /* '+' matches all hosts */
                hostok = 1;
                break;
            }
            if (buf[1] == '@')  /* match a host by netgroup */
                hostok = innetgr((char *)&buf[2],
                                 (char *)&hname, NULL, ypdomain);
            else		/* match a host by addr */
                hostok = __icheckhost(raddr,(char *)&buf[1]);
            break;
        case '-':     /* reject '-' hosts and all their users */
            if (buf[1] == '@') {
                if (innetgr((char *)&buf[2],
                            (char *)&hname, NULL, ypdomain))
                    return(-1);
            } else {
                if (__icheckhost(raddr,(char *)&buf[1]))
                    return(-1);
            }
            break;
        default:  /* if no '+' or '-', do a simple match */
            hostok = __icheckhost(raddr, buf);
            break;
        }
        switch(*user) {
        case '+':
            if (!*(user+1)) {      /* '+' matches all users */
                userok = 1;
                break;
            }
            if (*(user+1) == '@')  /* match a user by netgroup */
                userok = innetgr(user+2, NULL, (char *)ruser,
                                 ypdomain);
            else	   /* match a user by direct specification */
                userok = !(strcmp(ruser, user+1));
            break;
        case '-': 		/* if we matched a hostname, */
            if (hostok) {   /* check for user field rejections */
                if (!*(user+1))
                    return(-1);
                if (*(user+1) == '@') {
                    if (innetgr(user+2, NULL,
                                (char *)ruser, ypdomain))
                        return(-1);
                } else {
                    if (!strcmp(ruser, user+1))
                        return(-1);
                }
            }
            break;
        default:	/* no rejections: try to match the user */
            if (hostok)
                userok = !(strcmp(ruser,*user ? user : luser));
            break;
        }
        if (hostok && userok)
            return(0);
    }
    return (-1);
}
Beispiel #2
0
/*
 * Returns 0 if positive match, -1 if _not_ ok.
 */
static int
__ivaliduser2(FILE *hostf, u_int32_t raddr,	const char *luser,
              const char *ruser, const char *rhost)
{
    register const char *user;
    register char *p;
    int hcheck, ucheck;
    char *buf = NULL;
    size_t bufsize = 0;
    int retval = -1;

    while (getline (&buf, &bufsize, hostf) > 0) {
        buf[bufsize - 1] = '\0'; /* Make sure it's terminated.  */
        p = buf;

        /* Skip empty or comment lines */
        if (__isempty (p)) {
            continue;
        }

        /* Skip lines that are too long. */
        if (strchr (p, '\n') == NULL) {
            int ch = getc_unlocked (hostf);

            while (ch != '\n' && ch != EOF)
                ch = getc_unlocked (hostf);
            continue;
        }

        for (; *p && !isspace(*p); ++p) {
            *p = tolower (*p);
        }

        /* Next we want to find the permitted name for the remote user.  */
        if (*p == ' ' || *p == '\t') {
            /* <nul> terminate hostname and skip spaces */
            for (*p++='\0'; *p && isspace (*p); ++p);

            user = p;                   /* this is the user's name */
            while (*p && !isspace (*p))
                ++p;                    /* find end of user's name */
        } else
            user = p;

        *p = '\0';              /* <nul> terminate username (+host?) */

        /* buf -> host(?) ; user -> username(?) */

        /* First check host part */
        hcheck = __icheckhost (raddr, buf, rhost);

        if (hcheck < 0)
            break;

        if (hcheck) {
            /* Then check user part */
            if (! (*user))
                user = luser;

            ucheck = __icheckuser (user, ruser);

            /* Positive 'host user' match? */
            if (ucheck > 0) {
                retval = 0;
                break;
            }

            /* Negative 'host -user' match? */
            if (ucheck < 0)
                break;

            /* Neither, go on looking for match */
        }
    }

    free (buf);

    return retval;
}
Beispiel #3
0
int
__ivaliduser_sa(FILE *hostf, struct sockaddr *raddr, socklen_t salen,
    const char *luser, const char *ruser)
{
	char *user, *p;
	char *buf;
	const char *auser, *ahost;
	int hostok, userok;
	char *rhost = (char *)-1;
	char domain[MAXHOSTNAMELEN];
	size_t buflen;

	getdomainname(domain, sizeof(domain));

	while ((buf = fgetln(hostf, &buflen))) {
		p = buf;
		if (*p == '#')
			continue;
		while (p < buf + buflen && *p != '\n' && *p != ' ' && *p != '\t') {
			if (!isprint(*p))
				goto bail;
			*p = isupper(*p) ? tolower(*p) : *p;
			p++;
		}
		if (p >= buf + buflen)
			continue;
		if (*p == ' ' || *p == '\t') {
			*p++ = '\0';
			while (p < buf + buflen && (*p == ' ' || *p == '\t'))
				p++;
			if (p >= buf + buflen)
				continue;
			user = p;
			while (p < buf + buflen && *p != '\n' && *p != ' ' &&
			    *p != '\t') {
				if (!isprint(*p))
					goto bail;
				p++;
			}
		} else
			user = p;
		*p = '\0';

		if (p == buf)
			continue;

		auser = *user ? user : luser;
		ahost = buf;

		if (strlen(ahost) >= MAXHOSTNAMELEN)
			continue;

		/*
		 * innetgr() must lookup a hostname (we do not attempt
		 * to change the semantics so that netgroups may have
		 * #.#.#.# addresses in the list.)
		 */
		if (ahost[0] == '+')
			switch (ahost[1]) {
			case '\0':
				hostok = 1;
				break;
			case '@':
				if (rhost == (char *)-1)
					rhost = __gethostloop(raddr, salen);
				hostok = 0;
				if (rhost)
					hostok = innetgr(&ahost[2], rhost,
					    NULL, domain);
				break;
			default:
				hostok = __icheckhost(raddr, salen, &ahost[1]);
				break;
			}
		else if (ahost[0] == '-')
			switch (ahost[1]) {
			case '\0':
				hostok = -1;
				break;
			case '@':
				if (rhost == (char *)-1)
					rhost = __gethostloop(raddr, salen);
				hostok = 0;
				if (rhost)
					hostok = -innetgr(&ahost[2], rhost,
					    NULL, domain);
				break;
			default:
				hostok = -__icheckhost(raddr, salen, &ahost[1]);
				break;
			}
		else
			hostok = __icheckhost(raddr, salen, ahost);


		if (auser[0] == '+')
			switch (auser[1]) {
			case '\0':
				userok = 1;
				break;
			case '@':
				userok = innetgr(&auser[2], NULL, ruser,
				    domain);
				break;
			default:
				userok = strcmp(ruser, &auser[1]) ? 0 : 1;
				break;
			}
		else if (auser[0] == '-')
			switch (auser[1]) {
			case '\0':
				userok = -1;
				break;
			case '@':
				userok = -innetgr(&auser[2], NULL, ruser,
				    domain);
				break;
			default:
				userok = strcmp(ruser, &auser[1]) ? 0 : -1;
				break;
			}
		else
			userok = strcmp(ruser, auser) ? 0 : 1;

		/* Check if one component did not match */
		if (hostok == 0 || userok == 0)
			continue;

		/* Check if we got a forbidden pair */
		if (userok <= -1 || hostok <= -1)
			return (-1);

		/* Check if we got a valid pair */
		if (hostok >= 1 && userok >= 1)
			return (0);
	}
bail:
	return (-1);
}
Beispiel #4
0
int
__ivaliduser_sa(FILE *hostf, const struct sockaddr *raddr, socklen_t salen,
		const char *luser, const char *ruser)
{
	char *user, *p;
	int ch;
	char buf[MAXHOSTNAMELEN + 128];		/* host + login */
	char hname[MAXHOSTNAMELEN];
	/* Presumed guilty until proven innocent. */
	int userok = 0, hostok = 0;
#ifdef YP
	char *ypdomain;

	if (yp_get_default_domain(&ypdomain))
		ypdomain = NULL;
#else
#define	ypdomain NULL
#endif
	/* We need to get the damn hostname back for netgroup matching. */
	if (getnameinfo(raddr, salen, hname, sizeof(hname), NULL, 0,
			NI_NAMEREQD) != 0)
		hname[0] = '\0';

	while (fgets(buf, sizeof(buf), hostf)) {
		p = buf;
		/* Skip lines that are too long. */
		if (strchr(p, '\n') == NULL) {
			while ((ch = getc(hostf)) != '\n' && ch != EOF);
			continue;
		}
		if (*p == '\n' || *p == '#') {
			/* comment... */
			continue;
		}
		while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
			*p = isupper((unsigned char)*p) ? tolower((unsigned char)*p) : *p;
			p++;
		}
		if (*p == ' ' || *p == '\t') {
			*p++ = '\0';
			while (*p == ' ' || *p == '\t')
				p++;
			user = p;
			while (*p != '\n' && *p != ' ' &&
			    *p != '\t' && *p != '\0')
				p++;
		} else
			user = p;
		*p = '\0';
		/*
		 * Do +/- and +@/-@ checking. This looks really nasty,
		 * but it matches SunOS's behavior so far as I can tell.
		 */
		switch(buf[0]) {
		case '+':
			if (!buf[1]) {     /* '+' matches all hosts */
				hostok = 1;
				break;
			}
			if (buf[1] == '@')  /* match a host by netgroup */
				hostok = hname[0] != '\0' &&
				    innetgr(&buf[2], hname, NULL, ypdomain);
			else		/* match a host by addr */
				hostok = __icheckhost(raddr, salen,
						      (char *)&buf[1]);
			break;
		case '-':     /* reject '-' hosts and all their users */
			if (buf[1] == '@') {
				if (hname[0] == '\0' ||
				    innetgr(&buf[2], hname, NULL, ypdomain))
					return(-1);
			} else {
				if (__icheckhost(raddr, salen,
						 (char *)&buf[1]))
					return(-1);
			}
			break;
		default:  /* if no '+' or '-', do a simple match */
			hostok = __icheckhost(raddr, salen, buf);
			break;
		}
		switch(*user) {
		case '+':
			if (!*(user+1)) {      /* '+' matches all users */
				userok = 1;
				break;
			}
			if (*(user+1) == '@')  /* match a user by netgroup */
				userok = innetgr(user+2, NULL, ruser, ypdomain);
			else	   /* match a user by direct specification */
				userok = !(strcmp(ruser, user+1));
			break;
		case '-': 		/* if we matched a hostname, */
			if (hostok) {   /* check for user field rejections */
				if (!*(user+1))
					return(-1);
				if (*(user+1) == '@') {
					if (innetgr(user+2, NULL,
							ruser, ypdomain))
						return(-1);
				} else {
					if (!strcmp(ruser, user+1))
						return(-1);
				}
			}
			break;
		default:	/* no rejections: try to match the user */
			if (hostok)
				userok = !(strcmp(ruser,*user ? user : luser));
			break;
		}
		if (hostok && userok)
			return(0);
	}
	return (-1);
}
static int
__ivaliduser (pam_handle_t *pamh, struct _options *opts,
	      FILE *hostf, U32 raddr,
	      const char *luser, const char *ruser, const char *rhost)
{
    register const char *user;
    register char *p;
    int hcheck, ucheck;
    char buf[MAXHOSTNAMELEN + 128];                       /* host + login */

    buf[sizeof (buf)-1] = '\0';                 	/* terminate line */

    while (fgets(buf, sizeof(buf), hostf) != NULL) {   /* hostf file line */
        p = buf;                              /* from beginning of file.. */

	/* Skip empty or comment lines */
	if (__isempty(p)) {
	    continue;
	}

	/* Skip lines that are too long. */
	if (strchr(p, '\n') == NULL) {
	    int ch = getc(hostf);

	    while (ch != '\n' && ch != EOF)
		ch = getc(hostf);
	    continue;
	}

	/*
	 * If there is a hostname at the start of the line.  Set it to
	 * lower case. A leading ' ' or '\t' indicates no hostname
	 */

	for (;*p && !isspace(*p); ++p) {
	    *p = tolower(*p);
	}

	/*
	 * next we want to find the permitted name for the remote user
	 */

	if (*p == ' ' || *p == '\t') {

	    /* <nul> terminate hostname and skip spaces */
	    for (*p++='\0'; *p && isspace(*p); ++p);

	    user = p;                   /* this is the user's name */
	    while (*p && !isspace(*p))
		++p;                    /* find end of user's name */
	} else 
	    user = p;

	*p = '\0';              /* <nul> terminate username (+host?) */

	/* buf -> host(?) ; user -> username(?) */

	/* First check host part */
	hcheck=__icheckhost(pamh, opts, raddr, buf, rhost);

	if (hcheck<0)
	    return(1);

	if (hcheck) {
	    /* Then check user part */
	    if (! (*user))
		user = luser;

	    ucheck=__icheckuser(pamh, opts, user, ruser, rhost);

	    /* Positive 'host user' match? */
	    if (ucheck>0)
		return(0);

	    /* Negative 'host -user' match? */
	    if (ucheck<0)
		return(1);

	    /* Neither, go on looking for match */
	}
    }

    return (1);
}