static int __icheckuser(pam_handle_t *pamh, struct _options *opts
			, const char *luser, const char *ruser
			, const char *rhost)
{
    /*
      luser is user entry from .rhosts/hosts.equiv file
      ruser is user id on remote host
      rhost is the remote host name
      */
    char *user;

    /* [-+]@netgroup */
    if (strncmp("+@",luser,2) == 0)
	return (innetgr(&luser[2],NULL,ruser,NULL));

    if (strncmp("-@",luser,2) == 0)
	return (-innetgr(&luser[2],NULL,ruser,NULL));

    /* -user */
    if (strncmp("-",luser,1) == 0)
	return(-(strcmp(&luser[1],ruser) == 0));

    /* + */
    if (strcmp("+",luser) == 0) {
	(void) pam_get_item(pamh, PAM_USER, (const void **)&user);
	_pam_log(LOG_WARNING, "user %s has a `+' user entry", user);
	if (opts->opt_promiscuous)
	    return(1);
	/* If not promiscuous we handle it as a negative match */
	return(-1);
    }

    /* simple string match */
    return (strcmp(ruser, luser) == 0);
}
Example #2
0
/* Returns 1 on positive match, 0 on no match, -1 on negative match.  */
static int
__icheckuser (const char *luser, const char *ruser)
{

    /*
      luser is user entry from .rhosts/hosts.equiv file
      ruser is user id on remote host
      */

#ifdef HAVE_NETGROUP
    /* [-+]@netgroup */
    if (strncmp ("+@", luser, 2) == 0)
        return innetgr (&luser[2], NULL, ruser, NULL);

    if (strncmp ("-@", luser,2) == 0)
        return -innetgr (&luser[2], NULL, ruser, NULL);
#endif /* HAVE_NETGROUP */

    /* -user */
    if (strncmp ("-", luser, 1) == 0)
        return -(strcmp (&luser[1], ruser) == 0);

    /* + */
    if (strcmp ("+", luser) == 0)
        return 1;

    /* simple string match */
    return strcmp (ruser, luser) == 0;
}
static int
netgroup_match(const char *group, const char *machine, const char *user)
{
#if 0  /* original code */
#ifdef NIS
    static char *mydomain = 0;

    if (mydomain == 0)
	yp_get_default_domain(&mydomain);
    return (innetgr(group, machine, user, mydomain));
#else
    syslog(LOG_ERR, "NIS netgroup support not configured");
    return (NO);
#endif
#else  /* works better with glibc? */
	static char *mydomain = 0;

	if (mydomain == 0) {
		static char domain[MAXHOSTNAMELEN+1];

		getdomainname(domain, MAXHOSTNAMELEN);
		mydomain = domain;
	}

	return innetgr(group, machine, user, mydomain);
#endif
}
static int
__icheckhost (pam_handle_t *pamh, struct _options *opts, U32 raddr
	      , register char *lhost, const char *rhost)
{
    struct hostent *hp;
    U32 laddr;
    int negate=1;    /* Multiply return with this to get -1 instead of 1 */
    char **pp, *user;

    /* Check nis netgroup.  We assume that pam has done all needed
       paranoia checking before we are handed the rhost */
    if (strncmp("+@",lhost,2) == 0)
      return(innetgr(&lhost[2],rhost,NULL,NULL));

    if (strncmp("-@",lhost,2) == 0)
      return(-innetgr(&lhost[2],rhost,NULL,NULL));

    /* -host */
    if (strncmp("-",lhost,1) == 0) {
	negate=-1;
	lhost++;
    } else if (strcmp("+",lhost) == 0) {
        (void) pam_get_item(pamh, PAM_USER, (const void **)&user);
        D(("user %s has a `+' host entry", user));
	if (opts->opt_promiscuous)
	    return (1);                     /* asking for trouble, but ok.. */
	/* If not promiscuous: handle as negative */
	return (-1);
    } else if (strncmp("+",lhost,1) == 0) {
	/* '+hostname' is supposed to be equivalent to 'hostname' */
	lhost++;
    }


    /* Try for raw ip address first. */
    if (isdigit(*lhost) && (long)(laddr = inet_addr(lhost)) != -1)
	return (negate*(! (raddr ^ laddr)));

    /* Better be a hostname. */
    hp = gethostbyname(lhost);
    if (hp == NULL)
	return (0);
    
    /* Spin through ip addresses. */
    for (pp = hp->h_addr_list; *pp; ++pp)
	if (!memcmp (&raddr, *pp, sizeof (U32)))
	    return (negate);

    /* No match. */
    return (0);
}
bool user_in_netgroup(TALLOC_CTX *ctx, const char *user, const char *ngname)
{
#ifdef HAVE_NETGROUP
	static char *my_yp_domain = NULL;
	char *lowercase_user = NULL;

	if (my_yp_domain == NULL) {
		yp_get_default_domain(&my_yp_domain);
	}

	if (my_yp_domain == NULL) {
		DEBUG(5,("Unable to get default yp domain, "
			"let's try without specifying it\n"));
	}

	DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
		user, my_yp_domain?my_yp_domain:"(ANY)", ngname));

	if (innetgr(ngname, NULL, user, my_yp_domain)) {
		DEBUG(5,("user_in_netgroup: Found\n"));
		return true;
	}

	/*
	 * Ok, innetgr is case sensitive. Try once more with lowercase
	 * just in case. Attempt to fix #703. JRA.
	 */
	lowercase_user = talloc_strdup(ctx, user);
	if (!lowercase_user) {
		return false;
	}
	if (!strlower_m(lowercase_user)) {
		return false;
	}

	if (strcmp(user,lowercase_user) == 0) {
		/* user name was already lower case! */
		return false;
	}

	DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
		lowercase_user, my_yp_domain?my_yp_domain:"(ANY)", ngname));

	if (innetgr(ngname, NULL, lowercase_user, my_yp_domain)) {
		DEBUG(5,("user_in_netgroup: Found\n"));
		return true;
	}
#endif /* HAVE_NETGROUP */
	return false;
}
Example #6
0
static int
netgroup_match (pam_handle_t *pamh, const char *netgroup,
		const char *machine, const char *user, int debug)
{
  int retval;
  char *mydomain = NULL;

#ifdef HAVE_YP_GET_DEFAUTL_DOMAIN
  yp_get_default_domain(&mydomain);
#elif defined(HAVE_GETDOMAINNAME)
  char domainname_res[256];

  if (getdomainname (domainname_res, sizeof (domainname_res)) == 0)
    {
      if (domainname_res[0] != '\0' && strcmp (domainname_res, "(none)") != 0)
        {
          mydomain = domainname_res;
        }
    }
#endif

#ifdef HAVE_INNETGR
  retval = innetgr (netgroup, machine, user, mydomain);
#else
  retval = 0;
  pam_syslog (pamh, LOG_ERR, "pam_access does not have netgroup support");
#endif
  if (debug == YES)
    pam_syslog (pamh, LOG_DEBUG,
		"netgroup_match: %d (netgroup=%s, machine=%s, user=%s, domain=%s)",
		retval, netgroup ? netgroup : "NULL",
		machine ? machine : "NULL",
		user ? user : "******", mydomain ? mydomain : "NULL");
  return retval;
}
/* Return PAM_SUCCESS if the (host,user) is NOT in the netgroup. */
static int
evaluate_notinnetgr(const char *host, const char *user, const char *group)
{
	if (innetgr(group, host, user, NULL) == 0)
		return PAM_SUCCESS;
	return PAM_AUTH_ERR;
}
Example #8
0
static int netgroupUserMatch(void *priv, const struct SquidInfo *info)
{
	if (innetgr((char *)priv, NULL, info->ident, NULL)) {
		sgLogDebug("user '%s' is in netgroup %s", info->ident, priv);
		return 1;
	}

	return 0;
}
Example #9
0
/* test if this host (fully-qualified name) is in netgroup (arg) */
static int
f_netgrpd(char *arg)
{
  int status;

  status = innetgr(arg, opt_hostd, NULL, NULL);
  dlog("netgrp = %s status = %d hostd = %s", arg, status, opt_hostd);
  return status;
}
Example #10
0
static int netgroupHostMatch(void *priv, const struct SquidInfo *info)
{
	if (innetgr((char *)priv, NULL, info->domain, NULL)) {
		sgLogDebug("host '%s' is in netgroup %s", info->domain, priv);
		return 1;
	}

	return 0;
}
Example #11
0
/* Return PAM_SUCCESS if the (host,user) is NOT in the netgroup. */
static int
evaluate_notinnetgr(const pam_handle_t* pamh, const char *host, const char *user, const char *group)
{
#ifdef HAVE_INNETGR
	if (innetgr(group, host, user, NULL) == 0)
		return PAM_SUCCESS;
#else
	pam_syslog (pamh, LOG_ERR, "pam_succeed_if does not have netgroup support");
#endif
	return PAM_AUTH_ERR;
}
Example #12
0
NGR_R_RETURN
innetgr_r(const char *netgroup, const char *host, const char *user,
          const char *domain) {
    char *ng, *ho, *us, *dom;

    DE_CONST(netgroup, ng);
    DE_CONST(host, ho);
    DE_CONST(user, us);
    DE_CONST(domain, dom);

    return (innetgr(ng, ho, us, dom));
}
Example #13
0
BOOL user_in_netgroup(const char *user, const char *ngname)
{
#ifdef HAVE_NETGROUP
	static char *mydomain = NULL;
	fstring lowercase_user;

	if (mydomain == NULL)
		yp_get_default_domain(&mydomain);

	if(mydomain == NULL) {
		DEBUG(5,("Unable to get default yp domain, let's try without specifying it\n"));
	}

	DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
		user, mydomain?mydomain:"(ANY)", ngname));

	if (innetgr(ngname, NULL, user, mydomain)) {
		DEBUG(5,("user_in_netgroup: Found\n"));
		return (True);
	} else {

		/*
		 * Ok, innetgr is case sensitive. Try once more with lowercase
		 * just in case. Attempt to fix #703. JRA.
		 */

		fstrcpy(lowercase_user, user);
		strlower_m(lowercase_user);
	
		DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
			lowercase_user, mydomain?mydomain:"(ANY)", ngname));

		if (innetgr(ngname, NULL, lowercase_user, mydomain)) {
			DEBUG(5,("user_in_netgroup: Found\n"));
			return (True);
		}
	}
#endif /* HAVE_NETGROUP */
	return False;
}
Example #14
0
static BOOL user_in_netgroup_list(char *user,char *ngname)
{
#ifdef HAVE_NETGROUP
  static char *mydomain = NULL;
  if (mydomain == NULL)
    yp_get_default_domain(&mydomain);

  if(mydomain == NULL) {
    DEBUG(5,("Unable to get default yp domain\n"));
  } else {
    DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
          user, mydomain, ngname));
    DEBUG(5,("innetgr is %s\n",
          innetgr(ngname, NULL, user, mydomain)
          ? "TRUE" : "FALSE"));

    if (innetgr(ngname, NULL, user, mydomain))
      return (True);
  }
#endif /* HAVE_NETGROUP */
  return False;
}
Example #15
0
static int netgroup_match(char *group, char *machine, char *user)
{
#ifdef NIS
    static char *mydomain = 0;

    if (mydomain == 0)
	yp_get_default_domain(&mydomain);
    return (innetgr(group, machine, user, mydomain));
#else
    _log_err("NIS netgroup support not configured");
    return (NO);
#endif
}
Example #16
0
/* netgroup_match - match group against machine or user */
static bool
netgroup_match (const char *group, const char *machine, const char *user)
{
	static char *mydomain = (char *)0;

	if (mydomain == (char *)0) {
		static char domain[MAXHOSTNAMELEN + 1];

		getdomainname (domain, MAXHOSTNAMELEN);
		mydomain = domain;
	}

	return (innetgr (group, machine, user, mydomain) != 0);
}
Example #17
0
static int
netgroup_match(const char *group, const char *machine, const char *user)
{
    char domain[1024];
    unsigned int i;

    if (getdomainname(domain, sizeof(domain)) != 0 || *domain == '\0') {
        syslog(LOG_ERR, "NIS netgroup support disabled: no NIS domain");
        return (NO);
    }

    /* getdomainname() does not reliably terminate the string */
    for (i = 0; i < sizeof(domain); ++i)
        if (domain[i] == '\0')
            break;
    if (i == sizeof(domain)) {
        syslog(LOG_ERR, "NIS netgroup support disabled: invalid NIS domain");
        return (NO);
    }

    if (innetgr(group, machine, user, domain) == 1)
        return (YES);
    return (NO);
}
Example #18
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);
}
Example #19
0
/****************************************************************************
read the a hosts.equiv or .rhosts file and check if it
allows this user from this machine
****************************************************************************/
static BOOL check_user_equiv(char *user, char *remote, char *equiv_file)
{
  pstring buf;
  int plus_allowed = 1;
  char *file_host;
  char *file_user;
  FILE *fp = fopen(equiv_file, "r");
  DEBUG(5, ("check_user_equiv %s %s %s\n", user, remote, equiv_file));
  if (! fp) return False;
  while(fgets(buf, sizeof(buf), fp)) 
  {
    trim_string(buf," "," ");

    if (buf[0] != '#' && buf[0] != '\n') 
    {
      BOOL is_group = False;
      int plus = 1;
      char *bp = buf;
      if (strcmp(buf, "NO_PLUS\n") == 0)
      {
	DEBUG(6, ("check_user_equiv NO_PLUS\n"));
	plus_allowed = 0;
      }
      else {
	if (buf[0] == '+') 
	{
	  bp++;
	  if (*bp == '\n' && plus_allowed) 
	  {
	    /* a bare plus means everbody allowed */
	    DEBUG(6, ("check_user_equiv everybody allowed\n"));
	    fclose(fp);
	    return True;
	  }
	}
	else if (buf[0] == '-')
	{
	  bp++;
	  plus = 0;
	}
	if (*bp == '@') 
	{
	  is_group = True;
	  bp++;
	}
	file_host = strtok(bp, " \t\n");
	file_user = strtok(NULL, " \t\n");
	DEBUG(7, ("check_user_equiv %s %s\n", file_host ? file_host : "(null)", 
                 file_user ? file_user : "******" ));
	if (file_host && *file_host) 
	{
	  BOOL host_ok = False;

#ifdef NETGROUP	  
	  if (is_group)
	    {
	      static char *mydomain = NULL;
	      if (!mydomain)
		yp_get_default_domain(&mydomain);
	      if (mydomain && innetgr(file_host,remote,user,mydomain))
		host_ok = True;
	    }
#else
	  if (is_group)
	    {
	      DEBUG(1,("Netgroups not configured - add -DNETGROUP and recompile\n"));
	      continue;
	    }
#endif

	  /* is it this host */
	  /* the fact that remote has come from a call of gethostbyaddr
	   * means that it may have the fully qualified domain name
	   * so we could look up the file version to get it into
	   * a canonical form, but I would rather just type it
	   * in full in the equiv file
	   */
	  if (!host_ok && !is_group && strequal(remote, file_host))
	    host_ok = True;

	  if (!host_ok)
	    continue;

	  /* is it this user */
	  if (file_user == 0 || strequal(user, file_user)) 
	    {
	      fclose(fp);
	      DEBUG(5, ("check_user_equiv matched %s%s %s\n",
			(plus ? "+" : "-"), file_host,
			(file_user ? file_user : "")));
	      return (plus ? True : False);
	    }
	}
      }
    }
  }
  fclose(fp);
  return False;
}
Example #20
0
static int
_validuser(FILE *hostf, char *rhost, const char *luser,
    const char *ruser, int baselen)
{
	char *user;
	char ahost[BUFSIZ];
	char *uchost = (char *)NULL;
	int hostmatch, usermatch;
	char *p;

#ifdef NIS
	if (domain == NULL) {
		(void) usingypmap(&domain, NULL);
	}
#endif /* NIS */

	while (fgets(ahost, (int)sizeof (ahost), hostf)) {
		uchost = (char *)NULL;
		hostmatch = usermatch = 0;
		p = ahost;
		/*
		 * We can get a line bigger than our buffer.  If so we skip
		 * the offending line.
		 */
		if (strchr(p, '\n') == NULL) {
			while (fgets(ahost, (int)sizeof (ahost), hostf) &&
			    strchr(ahost, '\n') == NULL)
				;
			continue;
		}
		while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
			/*
			 *	Both host and user ``names'' can be netgroups,
			 *	and must have their case preserved.  Case is
			 *	preserved for user names because we break out
			 *	of this loop when finding a field separator.
			 *	To do so for host names, we must make a copy of
			 *	the host name field.
			 */
			if (isupper(*p)) {
				if (uchost == (char *)NULL)
					uchost = strdup(ahost);
				*p = tolower(*p);
			}
			p++;
		}
		if (*p != '\0' && uchost != (char *)NULL)
			uchost[p - ahost] = '\0';
		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';
		if (ahost[0] == '+' && ahost[1] == 0)
			hostmatch = 1;
#ifdef NIS
		else if (ahost[0] == '+' && ahost[1] == '@')
			if (uchost != (char *)NULL)
				hostmatch = innetgr(uchost + 2, rhost,
				    NULL, domain);
			else
				hostmatch = innetgr(ahost + 2, rhost,
				    NULL, domain);
		else if (ahost[0] == '-' && ahost[1] == '@') {
			if (uchost != (char *)NULL) {
				if (innetgr(uchost + 2, rhost, NULL, domain))
					break;
			} else {
				if (innetgr(ahost + 2, rhost, NULL, domain))
					break;
			}
		}
#endif /* NIS */
		else if (ahost[0] == '-') {
			if (_checkhost(rhost, ahost+1, baselen))
				break;
		}
		else
			hostmatch = _checkhost(rhost, ahost, baselen);
		if (user[0]) {
			if (user[0] == '+' && user[1] == 0)
				usermatch = 1;
#ifdef NIS
			else if (user[0] == '+' && user[1] == '@')
				usermatch = innetgr(user+2, NULL,
						    ruser, domain);
			else if (user[0] == '-' && user[1] == '@') {
				if (hostmatch &&
				    innetgr(user+2, NULL, ruser, domain))
					break;
			}
#endif /* NIS */
			else if (user[0] == '-') {
				if (hostmatch && (strcmp(user+1, ruser) == 0))
					break;
			}
			else
				usermatch = (strcmp(user, ruser) == 0);
		}
		else
			usermatch = (strcmp(ruser, luser) == 0);
		if (uchost != (char *)NULL)
			free(uchost);
		if (hostmatch && usermatch)
			return (0);
	}

	if (uchost != (char *)NULL)
		free(uchost);
	return (-1);
}
Example #21
0
/*ARGSUSED*/
int
pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
	FILE	*fd;
	const char	*allowdeny_filename = PF_PATH;
	char	buf[BUFSIZ];
	char	hostname[MAXHOSTNAMELEN];
	char	*username = NULL;
	char	*bufp;
	char	*rhost;
	char 	*limit;
	int	userok = 0;
	int	hostok = 0;
	int	i;
	int	allow_deny_test = 0;
	boolean_t	debug = B_FALSE;
	boolean_t	allow = B_FALSE;
	boolean_t	matched = B_FALSE;
	boolean_t	check_user = B_TRUE;
	boolean_t	check_host = B_FALSE;
	boolean_t	check_exact = B_FALSE;
	pam_list_mode_t	op_mode = LIST_PLUS_CHECK;

	for (i = 0; i < argc; ++i) {
		if (strncasecmp(argv[i], "debug", sizeof ("debug")) == 0) {
			debug = B_TRUE;
		} else if (strncasecmp(argv[i], "user", sizeof ("user")) == 0) {
			check_user = B_TRUE;
		} else if (strncasecmp(argv[i], "nouser",
		    sizeof ("nouser")) == 0) {
			check_user = B_FALSE;
		} else if (strncasecmp(argv[i], "host", sizeof ("host")) == 0) {
			check_host = B_TRUE;
		} else if (strncasecmp(argv[i], "nohost",
		    sizeof ("nohost")) == 0) {
			check_host = B_FALSE;
		} else if (strncasecmp(argv[i], "user_host_exact",
		    sizeof ("user_host_exact")) == 0) {
			check_exact = B_TRUE;
		} else if (strcasecmp(argv[i], "compat") == 0) {
			if (op_mode == LIST_PLUS_CHECK) {
				op_mode = LIST_COMPAT_MODE;
			} else {
				log_illegal_combination("compat",
				    string_mode_type(op_mode, allow));
				return (PAM_SERVICE_ERR);
			}
		} else if (strncasecmp(argv[i], "allow=",
		    sizeof ("allow=") - 1) == 0) {
			if (op_mode == LIST_PLUS_CHECK) {
				allowdeny_filename = argv[i] +
				    sizeof ("allow=") - 1;
				allow = B_TRUE;
				op_mode = LIST_EXTERNAL_FILE;
				allow_deny_test++;
			} else {
				log_illegal_combination("allow",
				    string_mode_type(op_mode, allow));
				return (PAM_SERVICE_ERR);
			}
		} else if (strncasecmp(argv[i], "deny=",
		    sizeof ("deny=") - 1) == 0) {
			if (op_mode == LIST_PLUS_CHECK) {
				allowdeny_filename = argv[i] +
				    sizeof ("deny=") - 1;
				allow = B_FALSE;
				op_mode = LIST_EXTERNAL_FILE;
				allow_deny_test++;
			} else {
				log_illegal_combination("deny",
				    string_mode_type(op_mode, allow));
				return (PAM_SERVICE_ERR);
			}
		} else {
			__pam_log(LOG_AUTH | LOG_ERR,
			    "pam_list: illegal option %s", argv[i]);
			return (PAM_SERVICE_ERR);
		}
	}

	if (((check_user || check_host || check_exact) == B_FALSE) ||
	    (allow_deny_test > 1)) {
		__pam_log(LOG_AUTH | LOG_ERR, ILLEGAL_COMBINATION);
		return (PAM_SERVICE_ERR);
	}

	if ((op_mode == LIST_COMPAT_MODE) && (check_user == B_FALSE)) {
		log_illegal_combination("compat", "nouser");
		return (PAM_SERVICE_ERR);
	}

	if (debug) {
		__pam_log(LOG_AUTH | LOG_DEBUG,
		    "pam_list: check_user = %d, check_host = %d,"
		    "check_exact = %d\n",
		    check_user, check_host, check_exact);

		__pam_log(LOG_AUTH | LOG_DEBUG,
		    "pam_list: auth_file: %s, %s\n", allowdeny_filename,
		    (op_mode == LIST_COMPAT_MODE) ? "compat mode" :
		    (allow ? "allow file" : "deny file"));
	}

	(void) pam_get_item(pamh, PAM_USER, (void**)&username);

	if ((check_user || check_exact) && ((username == NULL) ||
	    (*username == '\0'))) {
		__pam_log(LOG_AUTH | LOG_ERR,
		    "pam_list: username not supplied, critical error");
		return (PAM_USER_UNKNOWN);
	}

	(void) pam_get_item(pamh, PAM_RHOST, (void**)&rhost);

	if ((check_host || check_exact) && ((rhost == NULL) ||
	    (*rhost == '\0'))) {
		if (gethostname(hostname, MAXHOSTNAMELEN) == 0) {
			rhost = hostname;
		} else {
			__pam_log(LOG_AUTH | LOG_ERR,
			    "pam_list: error by gethostname - %m");
			return (PAM_SERVICE_ERR);
		}
	}

	if (debug) {
		__pam_log(LOG_AUTH | LOG_DEBUG,
		    "pam_list: pam_sm_acct_mgmt for (%s,%s,)",
		    (rhost != NULL) ? rhost : "", username);
	}

	if (strlen(allowdeny_filename) == 0) {
		__pam_log(LOG_AUTH | LOG_ERR,
		    "pam_list: file name not specified");
		return (PAM_SERVICE_ERR);
	}

	if ((fd = fopen(allowdeny_filename, "rF")) == NULL) {
		__pam_log(LOG_AUTH | LOG_ERR, "pam_list: fopen of %s: %s",
		    allowdeny_filename, strerror(errno));
		return (PAM_SERVICE_ERR);
	}

	while (fgets(buf, BUFSIZ, fd) != NULL) {
		/* lines longer than BUFSIZ-1 */
		if ((strlen(buf) == (BUFSIZ - 1)) &&
		    (buf[BUFSIZ - 2] != '\n')) {
			while ((fgetc(fd) != '\n') && (!feof(fd))) {
				continue;
			}
			__pam_log(LOG_AUTH | LOG_DEBUG,
			    "pam_list: long line in file,"
			    "more than %d chars, the rest ignored", BUFSIZ - 1);
		}

		/* remove unneeded colons if necessary */
		if ((limit = strpbrk(buf, ":\n")) != NULL) {
			*limit = '\0';
		}

		/* ignore free values */
		if (buf[0] == '\0') {
			continue;
		}

		bufp = buf;

		/* test for interesting lines = +/- in /etc/passwd */
		if (op_mode == LIST_COMPAT_MODE) {
			/* simple + matches all */
			if ((buf[0] == '+') && (buf[1] == '\0')) {
				matched = B_TRUE;
				allow = B_TRUE;
				break;
			}

			/* simple - is not defined */
			if ((buf[0] == '-') && (buf[1] == '\0')) {
				__pam_log(LOG_AUTH | LOG_ERR,
				    "pam_list: simple minus unknown, "
				    "illegal line in " PF_PATH);
				(void) fclose(fd);
				return (PAM_SERVICE_ERR);
			}

			/* @ is not allowed on the first position */
			if (buf[0] == '@') {
				__pam_log(LOG_AUTH | LOG_ERR,
				    "pam_list: @ is not allowed on the first "
				    "position in " PF_PATH);
				(void) fclose(fd);
				return (PAM_SERVICE_ERR);
			}

			/* -user or -@netgroup */
			if (buf[0] == '-') {
				allow = B_FALSE;
				bufp++;
			/* +user or +@netgroup */
			} else if (buf[0] == '+') {
				allow = B_TRUE;
				bufp++;
			/* user */
			} else {
				allow = B_TRUE;
			}
		} else if (op_mode == LIST_PLUS_CHECK) {
			if (((buf[0] != '+') && (buf[0] != '-')) ||
			    (buf[1] == '\0')) {
				continue;
			}

			if (buf[0] == '+') {
				allow = B_TRUE;
			} else {
				allow = B_FALSE;
			}
			bufp++;
		}

		/*
		 * if -> netgroup line
		 * else -> user line
		 */
		if ((bufp[0] == '@') && (bufp[1] != '\0')) {
			bufp++;

			if (check_exact) {
				if (innetgr(bufp, rhost, username,
				    NULL) == 1) {
					matched = B_TRUE;
					break;
				}
			} else {
				if (check_user) {
					userok = innetgr(bufp, NULL, username,
					    NULL);
				} else {
					userok = 1;
				}
				if (check_host) {
					hostok = innetgr(bufp, rhost, NULL,
					    NULL);
				} else {
					hostok = 1;
				}
				if (userok && hostok) {
					matched = B_TRUE;
					break;
				}
			}
		} else {
			if (check_user) {
				if (strcmp(bufp, username) == 0) {
					matched = B_TRUE;
					break;
				}
			}
		}

		/*
		 * No match found in /etc/passwd yet.  For compat mode
		 * a failure to match should result in a return of
		 * PAM_PERM_DENIED which is achieved below if 'matched'
		 * is false and 'allow' is true.
		 */
		if (op_mode == LIST_COMPAT_MODE) {
			allow = B_TRUE;
		}
	}
	(void) fclose(fd);

	if (debug) {
		__pam_log(LOG_AUTH | LOG_DEBUG,
		    "pam_list: %s for %s", matched ? "matched" : "no match",
		    allow ? "allow" : "deny");
	}

	if (matched) {
		return (allow ? PAM_SUCCESS : PAM_PERM_DENIED);
	}
	/*
	 * For compatibility with passwd_compat mode to prevent root access
	 * denied.
	 */
	if (op_mode == LIST_PLUS_CHECK) {
		return (PAM_IGNORE);
	}
	return (allow ? PAM_PERM_DENIED : PAM_SUCCESS);
}
Example #22
0
/* Returns 1 on positive match, 0 on no match, -1 on negative match.  */
static int
__icheckhost (u_int32_t raddr, char *lhost, const char *rhost)
{
    struct hostent *hp;
    u_int32_t laddr;
    int negate=1;    /* Multiply return with this to get -1 instead of 1 */
    char **pp;

#ifdef __UCLIBC_HAS_REENTRANT_RPC__
    int save_errno;
    size_t buflen;
    char *buffer;
    struct hostent hostbuf;
    int herr;
#endif

#ifdef HAVE_NETGROUP
    /* Check nis netgroup.  */
    if (strncmp ("+@", lhost, 2) == 0)
        return innetgr (&lhost[2], rhost, NULL, NULL);

    if (strncmp ("-@", lhost, 2) == 0)
        return -innetgr (&lhost[2], rhost, NULL, NULL);
#endif /* HAVE_NETGROUP */

    /* -host */
    if (strncmp ("-", lhost,1) == 0) {
        negate = -1;
        lhost++;
    } else if (strcmp ("+",lhost) == 0) {
        return 1;                    /* asking for trouble, but ok.. */
    }

    /* Try for raw ip address first. */
    if (isdigit (*lhost) && (laddr = inet_addr (lhost)) != INADDR_NONE)
        return negate * (! (raddr ^ laddr));

    /* Better be a hostname. */
#ifdef __UCLIBC_HAS_REENTRANT_RPC__
    buflen = 1024;
    buffer = malloc(buflen);
    save_errno = errno;

    while (gethostbyname_r (lhost, &hostbuf, buffer, buflen, &hp, &herr)
            != 0) {
        free(buffer);
        return (0);
    }
    free(buffer);
    __set_errno (save_errno);
#else
    hp = gethostbyname(lhost);
#endif /* __UCLIBC_HAS_REENTRANT_RPC__ */

    if (hp == NULL)
        return 0;

    /* Spin through ip addresses. */
    for (pp = hp->h_addr_list; *pp; ++pp)
        if (!memcmp (&raddr, *pp, sizeof (u_int32_t)))
            return negate;

    /* No match. */
    return (0);
}
Example #23
0
/* update our image of the net-group of trustworthy hosts
 */
void
get_goodgroup(int force)
{
# define NG_DELAY (30*60*CLK_TCK)	/* 30 minutes */
	static unsigned long last_update = -NG_DELAY;
	unsigned long new_update;
	struct goodhost *ghp, **ghpp;
#ifdef HAVENIS
	struct hosttbl *htp;
	char *mach, *usr, *dom;
#endif /* HAVENIS */
	struct tms tm;


	/* if no netgroup, then we are finished */
	if (goodgroup == NULL || !Mflag)
		return;

	/* Do not chatter with the netgroup master too often.
	 */
	new_update = times(&tm);
	if (new_update < last_update + NG_DELAY
	    && !force)
		return;
	last_update = new_update;

	/* forget the old temporary entries */
	ghpp = &goodhosts;
	while ((ghp = *ghpp) != NULL) {
		if (!ghp->perm) {
			*ghpp = ghp->next;
			free(ghp);
		} else {
			ghpp = &ghp->next;
		}
	}

#ifdef HAVENIS
	/* quit now if we are not one of the trusted masters
	 */
	if (!innetgr(goodgroup, &hostname[0], 0,0)) {
		if (trace)
			(void)fprintf(fd, "get_goodgroup: %s not in %s\n",
				      &hostname[0], goodgroup);
		return;
	}
	if (trace)
		(void)fprintf(fd, "get_goodgroup: %s in %s\n",
				  &hostname[0], goodgroup);

	/* mark the entire netgroup as trusted */
	(void)setnetgrent(goodgroup);
	while (getnetgrent(&mach,&usr,&dom)) {
		if (mach != NULL)
			add_good_host(mach,0);
	}
	(void)endnetgrent();

	/* update list of slaves */
	for (htp = self.l_fwd; htp != &self; htp = htp->l_fwd) {
		htp->good = good_host_name(&htp->name[0]);
	}
#endif /* HAVENIS */
}
Example #24
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);
}
Example #25
0
/* string_match - match string against token */
static int string_match(char *tok,char *s)
{
    int     tok_len;
    int     str_len;
    char   *cut;

    /*
     * Return YES if a token has the magic value "ALL". Return FAIL if the
     * token is "FAIL". If the token starts with a "." (domain name), return
     * YES if it matches the last fields of the string. If the token has the
     * magic value "LOCAL", return YES if the string does not contain a "."
     * character. If the token ends on a "." (network number), return YES if
     * it matches the first fields of the string. If the token begins with a
     * "@" (netgroup name), return YES if the string is a (host) member of
     * the netgroup. Return YES if the token fully matches the string. If the
     * token is a netnumber/netmask pair, return YES if the address is a
     * member of the specified subnet.
     */

    if (tok[0] == '.') {			/* domain: match last fields */
	if ((str_len = strlen(s)) > (tok_len = strlen(tok))
	    && strcasecmp(tok, s + str_len - tok_len) == 0)
	    return (YES);
    } else if (tok[0] == '@') {			/* netgroup: look it up */
#ifdef	NETGROUP
      static char *mydomain = NULL;
      char *hostname = NULL;
      BOOL netgroup_ok = False;

      if (!mydomain) yp_get_default_domain(&mydomain);

      if (!mydomain) {
        DEBUG(0,("Unable to get default yp domain.\n"));
        return NO;
      }
      if (!(hostname = strdup(s))) {
	DEBUG(1,("out of memory for strdup!\n"));
	return NO;
      }

      netgroup_ok = innetgr(tok + 1, hostname, (char *) 0, mydomain);

      DEBUG(5,("looking for %s of domain %s in netgroup %s gave %s\n", 
	       hostname,
	       mydomain, 
	       tok+1,
	       BOOLSTR(netgroup_ok)));

#ifdef NETGROUP_INSECURE
      /* if you really want netgroups that match non qualified names
	 then define NETGROUP_INSECURE. It can, however, be a big
	 security hole */
      {
	char        *clnt_domain;
	if (!netgroup_ok && (clnt_domain=strchr(hostname,'.'))) {
	  *clnt_domain++ = '\0';
	  netgroup_ok = innetgr(tok + 1, hostname, (char *) 0, mydomain);
	}
      }
#endif

      free(hostname);
      
      if (netgroup_ok) return(YES);
#else
      DEBUG(0,("access: netgroup support is not configured\n"));
      return (NO);
#endif
    } else if (strcasecmp(tok, "ALL") == 0) {	/* all: match any */
	return (YES);
    } else if (strcasecmp(tok, "FAIL") == 0) {	/* fail: match any */
	return (FAIL);
    } else if (strcasecmp(tok, "LOCAL") == 0) {	/* local: no dots */
	if (strchr(s, '.') == 0 && strcasecmp(s, "unknown") != 0)
	    return (YES);
    } else if (!strcasecmp(tok, s)) {	/* match host name or address */
	return (YES);
    } else if (tok[(tok_len = strlen(tok)) - 1] == '.') {	/* network */
	if (strncmp(tok, s, tok_len) == 0)
	    return (YES);
    } else if ((cut = strchr(tok, '/')) != 0) {	/* netnumber/netmask */
	if (isdigit(s[0]) && masked_match(tok, cut, s))
	    return (YES);
    }
    return (NO);
}
Example #26
0
int
fullLock(void)
{
	uid_t       uid;
	int         ngroups = NGROUPS;

#ifdef SUNOS4
	gid_t       mygidset[NGROUPS * sizeof (gid_t)];

#else
	gid_t       mygidset[NGROUPS];

#endif
	int         ngrps, i;
	struct passwd *pwp;
	struct group *gp;
	FILE       *fp;
	char        buf[BUFSIZ];
#ifndef NO_NEGATIVE_LOGOUT

	if (logoutButton < 0)
		return (FULL_LOCK);
#endif
	/* The debug portion may depend on what you are debugging.  :) */
	if (inwindow || inroot || nolock /*|| debug */ )
		return (FULL_LOCK);	/* (mostly) harmless user */
	uid = getuid();
	/* Do not try to logout root! */
	if (!uid)
		return (FULL_LOCK);	/* root */

	pwp = getpwuid(uid);
	if ((ngrps = getgroups(ngroups, mygidset)) == -1)
		perror(ProgramName);

#ifdef STAFF_NETGROUP
	if (innetgr(STAFF_NETGROUP, NULL, pwp->pw_name, NULL))
		return (FULL_LOCK);
#endif

	if ((fp = my_fopen(STAFF_FILE, "r")) == NULL)
		return (TEMP_LOCK);

	while ((fgets(buf, BUFSIZ, fp)) != NULL) {
		char       *cp;

		if ((cp = (char *) strchr(buf, '\n')) != NULL)
			*cp = '\0';
		if (!strcmp(buf, pwp->pw_name))
			return (FULL_LOCK);
		if ((gp = getgrnam(buf)) != NULL) {
			/* check all of user's groups */
#ifdef SUNOS4
			for (i = 1; i < ngrps * sizeof (gid_t); i += 2)
#else
			for (i = 0; i < ngrps; ++i)
#endif
				if (gp->gr_gid == mygidset[i])
					return (FULL_LOCK);
		}
	}
	(void) fclose(fp);

	return (TEMP_LOCK);
}
Example #27
0
/* string_match - match string s against token tok */
static bool string_match(const char *tok,const char *s)
{
	size_t     tok_len;
	size_t     str_len;
	const char   *cut;

	/* Return true if a token has the magic value "ALL". Return
	 * true if the token is "FAIL". If the token starts with a "."
	 * (domain name), return true if it matches the last fields of
	 * the string. If the token has the magic value "LOCAL",
	 * return true if the string does not contain a "."
	 * character. If the token ends on a "." (network number),
	 * return true if it matches the first fields of the
	 * string. If the token begins with a "@" (netgroup name),
	 * return true if the string is a (host) member of the
	 * netgroup. Return true if the token fully matches the
	 * string. If the token is a netnumber/netmask pair, return
	 * true if the address is a member of the specified subnet.
	 */

	if (tok[0] == '.') {			/* domain: match last fields */
		if ((str_len = strlen(s)) > (tok_len = strlen(tok))
		    && strequal(tok, s + str_len - tok_len)) {
			return true;
		}
	} else if (tok[0] == '@') { /* netgroup: look it up */
#ifdef	HAVE_NETGROUP
		DATA_BLOB tmp;
		char *mydomain = NULL;
		char *hostname = NULL;
		bool netgroup_ok = false;

		if (memcache_lookup(
			    NULL, SINGLETON_CACHE,
			    data_blob_string_const_null("yp_default_domain"),
			    &tmp)) {

			SMB_ASSERT(tmp.length > 0);
			mydomain = (tmp.data[0] == '\0')
				? NULL : (char *)tmp.data;
		}
		else {
			yp_get_default_domain(&mydomain);

			memcache_add(
				NULL, SINGLETON_CACHE,
				data_blob_string_const_null("yp_default_domain"),
				data_blob_string_const_null(mydomain?mydomain:""));
		}

		if (!mydomain) {
			DEBUG(0,("Unable to get default yp domain. "
				"Try without it.\n"));
		}
		if (!(hostname = SMB_STRDUP(s))) {
			DEBUG(1,("out of memory for strdup!\n"));
			return false;
		}

		netgroup_ok = innetgr(tok + 1, hostname, (char *) 0, mydomain);

		DEBUG(5,("looking for %s of domain %s in netgroup %s gave %s\n",
			 hostname,
			 mydomain?mydomain:"(ANY)",
			 tok+1,
			 BOOLSTR(netgroup_ok)));

		SAFE_FREE(hostname);

		if (netgroup_ok)
			return true;
#else
		DEBUG(0,("access: netgroup support is not configured\n"));
		return false;
#endif
	} else if (strequal(tok, "ALL")) {	/* all: match any */
		return true;
	} else if (strequal(tok, "FAIL")) {	/* fail: match any */
		return true;
	} else if (strequal(tok, "LOCAL")) {	/* local: no dots */
		if (strchr_m(s, '.') == 0 && !strequal(s, "unknown")) {
			return true;
		}
	} else if (strequal(tok, s)) {   /* match host name or address */
		return true;
	} else if (tok[(tok_len = strlen(tok)) - 1] == '.') {	/* network */
		if (strncmp(tok, s, tok_len) == 0) {
			return true;
		}
	} else if ((cut = strchr_m(tok, '/')) != 0) {	/* netnumber/netmask */
		if ((isdigit(s[0]) && strchr_m(tok, '.') != NULL) ||
			(tok[0] == '[' && cut > tok && cut[-1] == ']') ||
			((isxdigit(s[0]) || s[0] == ':') &&
				strchr_m(tok, ':') != NULL)) {
			/* IPv4/netmask or
			 * [IPv6:addr]/netmask or IPv6:addr/netmask */
			return masked_match(tok, cut, s);
		}
	} else if (strchr_m(tok, '*') != 0 || strchr_m(tok, '?')) {
		return unix_wild_match(tok, s);
	}
	return false;
}
Example #28
0
int
_validuser(FILE *hostf, char *rhost, char *luser, char *ruser, int baselen)
{
	char *user;
	char ahost[MAXHOSTNAMELEN];
	int hostmatch, usermatch;
	char *p;

	if (domain == NULL) {
                (void) yp_get_default_domain(&domain);
        }
	while (fgets(ahost, sizeof (ahost), hostf)) {
		hostmatch = usermatch = 0;	/* bugid fix 1033104 */
		p = ahost;
		while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
			*p = isupper(*p) ? tolower(*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';
		if (ahost[0] == '+' && ahost[1] == 0)
			hostmatch = 1;
		else if (ahost[0] == '+' && ahost[1] == '@')
			hostmatch = innetgr(ahost + 2, rhost,
			    NULL, domain);
		else if (ahost[0] == '-' && ahost[1] == '@') {
			if (innetgr(ahost + 2, rhost, NULL, domain))
				break;
		}
		else if (ahost[0] == '-') {
			if (_checkhost(rhost, ahost+1, baselen))
				break;
		}
		else
			hostmatch = _checkhost(rhost, ahost, baselen);
		if (user[0]) {
			if (user[0] == '+' && user[1] == 0)
				usermatch = 1;
			else if (user[0] == '+' && user[1] == '@')
				usermatch = innetgr(user+2, NULL,
				    ruser, domain);
			else if (user[0] == '-' && user[1] == '@') {
				if (hostmatch && innetgr(user+2, NULL,
				    ruser, domain))
					break;
			}
			else if (user[0] == '-') {
				if (hostmatch && !strcmp(user+1, ruser))
					break;
			}
			else
				usermatch = !strcmp(user, ruser);
		}
		else
			usermatch = !strcmp(ruser, luser);
		if (hostmatch && usermatch)
			return (0);
	}
	return (-1);
}
Example #29
0
static int
check_rhosts_file(const char *filename, const char *hostname,
		  const char *ipaddr, const char *client_user,
		  const char *server_user)
{
	FILE *f;
	char buf[1024];	/* Must not be larger than host, user, dummy below. */
	int fd;
	struct stat st;

	/* Open the .rhosts file, deny if unreadable */
	if ((fd = open(filename, O_RDONLY|O_NONBLOCK)) == -1)
		return 0;
	if (fstat(fd, &st) == -1) {
		close(fd);
		return 0;
	}
	if (!S_ISREG(st.st_mode)) {
		logit("User %s hosts file %s is not a regular file",
		    server_user, filename);
		close(fd);
		return 0;
	}
	unset_nonblock(fd);
	if ((f = fdopen(fd, "r")) == NULL) {
		close(fd);
		return 0;
	}
	while (fgets(buf, sizeof(buf), f)) {
		/* All three must be at least as big as buf to avoid overflows. */
		char hostbuf[1024], userbuf[1024], dummy[1024], *host, *user, *cp;
		int negated;

		for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
			;
		if (*cp == '#' || *cp == '\n' || !*cp)
			continue;

		/*
		 * NO_PLUS is supported at least on OSF/1.  We skip it (we
		 * don't ever support the plus syntax).
		 */
		if (strncmp(cp, "NO_PLUS", 7) == 0)
			continue;

		/*
		 * This should be safe because each buffer is as big as the
		 * whole string, and thus cannot be overwritten.
		 */
		switch (sscanf(buf, "%1023s %1023s %1023s", hostbuf, userbuf,
		    dummy)) {
		case 0:
			auth_debug_add("Found empty line in %.100s.", filename);
			continue;
		case 1:
			/* Host name only. */
			strlcpy(userbuf, server_user, sizeof(userbuf));
			break;
		case 2:
			/* Got both host and user name. */
			break;
		case 3:
			auth_debug_add("Found garbage in %.100s.", filename);
			continue;
		default:
			/* Weird... */
			continue;
		}

		host = hostbuf;
		user = userbuf;
		negated = 0;

		/* Process negated host names, or positive netgroups. */
		if (host[0] == '-') {
			negated = 1;
			host++;
		} else if (host[0] == '+')
			host++;

		if (user[0] == '-') {
			negated = 1;
			user++;
		} else if (user[0] == '+')
			user++;

		/* Check for empty host/user names (particularly '+'). */
		if (!host[0] || !user[0]) {
			/* We come here if either was '+' or '-'. */
			auth_debug_add("Ignoring wild host/user names in %.100s.",
			    filename);
			continue;
		}
		/* Verify that host name matches. */
		if (host[0] == '@') {
			if (!innetgr(host + 1, hostname, NULL, NULL) &&
			    !innetgr(host + 1, ipaddr, NULL, NULL))
				continue;
		} else if (strcasecmp(host, hostname) && strcmp(host, ipaddr) != 0)
			continue;	/* Different hostname. */

		/* Verify that user name matches. */
		if (user[0] == '@') {
			if (!innetgr(user + 1, NULL, client_user, NULL))
				continue;
		} else if (strcmp(user, client_user) != 0)
			continue;	/* Different username. */

		/* Found the user and host. */
		fclose(f);

		/* If the entry was negated, deny access. */
		if (negated) {
			auth_debug_add("Matched negative entry in %.100s.",
			    filename);
			return 0;
		}
		/* Accept authentication. */
		return 1;
	}

	/* Authentication using this file denied. */
	fclose(f);
	return 0;
}
Example #30
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);
}