⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 map.c

📁 < linux网络编程工具>>配套源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	(void) strlcpy(host_record, vp, sizeof host_record);
	free(vp);
	if (tTd(38, 44))
		dprintf("got record `%s'\n", host_record);
	if (!extract_canonname(nbuf, host_record, cbuf, sizeof cbuf))
	{
		/* this should not happen, but.... */
		*statp = EX_NOHOST;
		return FALSE;
	}
	if (hbsize < strlen(cbuf))
	{
		*statp = EX_UNAVAILABLE;
		return FALSE;
	}
	(void) strlcpy(name, cbuf, hbsize);
	*statp = EX_OK;
	return TRUE;
}

#endif /* NIS */
/*
**  NISPLUS Modules
**
**	This code donated by Sun Microsystems.
*/

#ifdef NISPLUS

# undef NIS		/* symbol conflict in nis.h */
# undef T_UNSPEC	/* symbol conflict in nis.h -> ... -> sys/tiuser.h */
# include <rpcsvc/nis.h>
# include <rpcsvc/nislib.h>

# define EN_col(col)	zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val
# define COL_NAME(res,i)	((res->objects.objects_val)->TA_data.ta_cols.ta_cols_val)[i].tc_name
# define COL_MAX(res)	((res->objects.objects_val)->TA_data.ta_cols.ta_cols_len)
# define PARTIAL_NAME(x)	((x)[strlen(x) - 1] != '.')

/*
**  NISPLUS_MAP_OPEN -- open nisplus table
*/

bool
nisplus_map_open(map, mode)
	MAP *map;
	int mode;
{
	nis_result *res = NULL;
	int retry_cnt, max_col, i;
	char qbuf[MAXLINE + NIS_MAXNAMELEN];

	if (tTd(38, 2))
		dprintf("nisplus_map_open(%s, %s, %d)\n",
			map->map_mname, map->map_file, mode);

	mode &= O_ACCMODE;
	if (mode != O_RDONLY)
	{
		errno = EPERM;
		return FALSE;
	}

	if (*map->map_file == '\0')
		map->map_file = "mail_aliases.org_dir";

	if (PARTIAL_NAME(map->map_file) && map->map_domain == NULL)
	{
		/* set default NISPLUS Domain to $m */
		map->map_domain = newstr(nisplus_default_domain());
		if (tTd(38, 2))
			dprintf("nisplus_map_open(%s): using domain %s\n",
				map->map_file, map->map_domain);
	}
	if (!PARTIAL_NAME(map->map_file))
	{
		map->map_domain = newstr("");
		snprintf(qbuf, sizeof qbuf, "%s", map->map_file);
	}
	else
	{
		/* check to see if this map actually exists */
		snprintf(qbuf, sizeof qbuf, "%s.%s",
			map->map_file, map->map_domain);
	}

	retry_cnt = 0;
	while (res == NULL || res->status != NIS_SUCCESS)
	{
		res = nis_lookup(qbuf, FOLLOW_LINKS);
		switch (res->status)
		{
		  case NIS_SUCCESS:
			break;

		  case NIS_TRYAGAIN:
		  case NIS_RPCERROR:
		  case NIS_NAMEUNREACHABLE:
			if (retry_cnt++ > 4)
			{
				errno = EAGAIN;
				return FALSE;
			}
			/* try not to overwhelm hosed server */
			sleep(2);
			break;

		  default:		/* all other nisplus errors */
# if 0
			if (!bitset(MF_OPTIONAL, map->map_mflags))
				syserr("421 4.0.0 Cannot find table %s.%s: %s",
					map->map_file, map->map_domain,
					nis_sperrno(res->status));
# endif /* 0 */
			errno = EAGAIN;
			return FALSE;
		}
	}

	if (NIS_RES_NUMOBJ(res) != 1 ||
	    (NIS_RES_OBJECT(res)->zo_data.zo_type != TABLE_OBJ))
	{
		if (tTd(38, 10))
			dprintf("nisplus_map_open: %s is not a table\n", qbuf);
# if 0
		if (!bitset(MF_OPTIONAL, map->map_mflags))
			syserr("421 4.0.0 %s.%s: %s is not a table",
				map->map_file, map->map_domain,
				nis_sperrno(res->status));
# endif /* 0 */
		errno = EBADF;
		return FALSE;
	}
	/* default key column is column 0 */
	if (map->map_keycolnm == NULL)
		map->map_keycolnm = newstr(COL_NAME(res,0));

	max_col = COL_MAX(res);

	/* verify the key column exist */
	for (i = 0; i< max_col; i++)
	{
		if (strcmp(map->map_keycolnm, COL_NAME(res,i)) == 0)
			break;
	}
	if (i == max_col)
	{
		if (tTd(38, 2))
			dprintf("nisplus_map_open(%s): can not find key column %s\n",
				map->map_file, map->map_keycolnm);
		errno = ENOENT;
		return FALSE;
	}

	/* default value column is the last column */
	if (map->map_valcolnm == NULL)
	{
		map->map_valcolno = max_col - 1;
		return TRUE;
	}

	for (i = 0; i< max_col; i++)
	{
		if (strcmp(map->map_valcolnm, COL_NAME(res,i)) == 0)
		{
			map->map_valcolno = i;
			return TRUE;
		}
	}

	if (tTd(38, 2))
		dprintf("nisplus_map_open(%s): can not find column %s\n",
			map->map_file, map->map_keycolnm);
	errno = ENOENT;
	return FALSE;
}


/*
**  NISPLUS_MAP_LOOKUP -- look up a datum in a NISPLUS table
*/

char *
nisplus_map_lookup(map, name, av, statp)
	MAP *map;
	char *name;
	char **av;
	int *statp;
{
	char *p;
	auto int vsize;
	char *skp;
	int skleft;
	char search_key[MAXNAME + 4];
	char qbuf[MAXLINE + NIS_MAXNAMELEN];
	nis_result *result;

	if (tTd(38, 20))
		dprintf("nisplus_map_lookup(%s, %s)\n",
			map->map_mname, name);

	if (!bitset(MF_OPEN, map->map_mflags))
	{
		if (nisplus_map_open(map, O_RDONLY))
		{
			map->map_mflags |= MF_OPEN;
			map->map_pid = getpid();
		}
		else
		{
			*statp = EX_UNAVAILABLE;
			return NULL;
		}
	}

	/*
	**  Copy the name to the key buffer, escaping double quote characters
	**  by doubling them and quoting "]" and "," to avoid having the
	**  NIS+ parser choke on them.
	*/

	skleft = sizeof search_key - 4;
	skp = search_key;
	for (p = name; *p != '\0' && skleft > 0; p++)
	{
		switch (*p)
		{
		  case ']':
		  case ',':
			/* quote the character */
			*skp++ = '"';
			*skp++ = *p;
			*skp++ = '"';
			skleft -= 3;
			break;

		  case '"':
			/* double the quote */
			*skp++ = '"';
			skleft--;
			/* FALLTHROUGH */

		  default:
			*skp++ = *p;
			skleft--;
			break;
		}
	}
	*skp = '\0';
	if (!bitset(MF_NOFOLDCASE, map->map_mflags))
		makelower(search_key);

	/* construct the query */
	if (PARTIAL_NAME(map->map_file))
		snprintf(qbuf, sizeof qbuf, "[%s=%s],%s.%s",
			map->map_keycolnm, search_key, map->map_file,
			map->map_domain);
	else
		snprintf(qbuf, sizeof qbuf, "[%s=%s],%s",
			map->map_keycolnm, search_key, map->map_file);

	if (tTd(38, 20))
		dprintf("qbuf=%s\n", qbuf);
	result = nis_list(qbuf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
	if (result->status == NIS_SUCCESS)
	{
		int count;
		char *str;

		if ((count = NIS_RES_NUMOBJ(result)) != 1)
		{
			if (LogLevel > 10)
				sm_syslog(LOG_WARNING, CurEnv->e_id,
					  "%s: lookup error, expected 1 entry, got %d",
					  map->map_file, count);

			/* ignore second entry */
			if (tTd(38, 20))
				dprintf("nisplus_map_lookup(%s), got %d entries, additional entries ignored\n",
					name, count);
		}

		p = ((NIS_RES_OBJECT(result))->EN_col(map->map_valcolno));
		/* set the length of the result */
		if (p == NULL)
			p = "";
		vsize = strlen(p);
		if (tTd(38, 20))
			dprintf("nisplus_map_lookup(%s), found %s\n",
				name, p);
		if (bitset(MF_MATCHONLY, map->map_mflags))
			str = map_rewrite(map, name, strlen(name), NULL);
		else
			str = map_rewrite(map, p, vsize, av);
		nis_freeresult(result);
		*statp = EX_OK;
		return str;
	}
	else
	{
		if (result->status == NIS_NOTFOUND)
			*statp = EX_NOTFOUND;
		else if (result->status == NIS_TRYAGAIN)
			*statp = EX_TEMPFAIL;
		else
		{
			*statp = EX_UNAVAILABLE;
			map->map_mflags &= ~(MF_VALID|MF_OPEN);
		}
	}
	if (tTd(38, 20))
		dprintf("nisplus_map_lookup(%s), failed\n", name);
	nis_freeresult(result);
	return NULL;
}



/*
**  NISPLUS_GETCANONNAME -- look up canonical name in NIS+
*/

static bool
nisplus_getcanonname(name, hbsize, statp)
	char *name;
	int hbsize;
	int *statp;
{
	char *vp;
	auto int vsize;
	nis_result *result;
	char *p;
	char nbuf[MAXNAME + 1];
	char qbuf[MAXLINE + NIS_MAXNAMELEN];

	if (strlen(name) >= sizeof nbuf)
	{
		*statp = EX_UNAVAILABLE;
		return FALSE;
	}
	(void) strlcpy(nbuf, name, sizeof nbuf);
	shorten_hostname(nbuf);

	p = strchr(nbuf, '.');
	if (p == NULL)
	{
		/* single token */
		snprintf(qbuf, sizeof qbuf, "[name=%s],hosts.org_dir", nbuf);
	}
	else if (p[1] != '\0')
	{
		/* multi token -- take only first token in nbuf */
		*p = '\0';
		snprintf(qbuf, sizeof qbuf, "[name=%s],hosts.org_dir.%s",
			nbuf, &p[1]);
	}
	else
	{
		*statp = EX_NOHOST;
		return FALSE;
	}

	if (tTd(38, 20))
		dprintf("\nnisplus_getcanoname(%s), qbuf=%s\n",
			name, qbuf);

	result = nis_list(qbuf, EXPAND_NAME|FOLLOW_LINKS|FOLLOW_PATH,
		NULL, NULL);

	if (result->status == NIS_SUCCESS)
	{
		int count;
		char *domain;

		if ((count = NIS_RES_NUMOBJ(result)) != 1)
		{
			if (LogLevel > 10)
				sm_syslog(LOG_WARNING, CurEnv->e_id,
					  "nisplus_getcanonname: lookup error, expected 1 entry, got %d",
					  count);

			/* ignore second entry */
			if (tTd(38, 20))
				dprintf("nisplus_getcanoname(%s), got %d entries, all but first ignored\n",
					name, count);
		}

		if (tTd(38, 20))
			dprintf("nisplus_getcanoname(%s), found in directory \"%s\"\n",
				name, (NIS_RES_OBJECT(result))->zo_domain);


		vp = ((NIS_RES_OBJECT(result))->EN_col(0));
		vsize = strlen(vp);
		if (tTd(38, 20))
			dprintf("nisplus_getcanonname(%s), found %s\n",
				name, vp);
		if (strchr(vp, '.') != NULL)
		{
			domain = "";
		}
		else
		{
			domain = macvalue('m', CurEnv);
			if (domain == NULL)
				domain = "";
		}
		if (hbsize > vsize + (int) strlen(domain) + 1)
		{
			if (domain[0] == '\0')
				(void) strlcpy(name, vp, hbsize);
			else
				snprintf(name, hbsize, "%s.%s", vp, domain);
			*statp = EX_OK;
		}
		else
			*statp = EX_NOHOST;
		nis_freeresult(result);
		return TRUE;
	}
	else
	{
		if (result->status == NIS_NOTFOUND)
			*statp = EX_NOHOST;
		else if (result->status == NIS_TRYAGAIN)
			*statp = EX_TEMPFAIL;
		else
			*statp = EX_UNAVAILABLE;
	}
	if (tTd(38, 20))
		dprintf("nisplus_getcanonname(%s), failed, status=%d, nsw_stat=%d\n",
			name, result->status, *statp);
	nis_freeresult(result);
	return FALSE;
}

char *
nisplus_default_domain()
{
	static char default_domain[MAXNAME + 1] = "";
	char *p;

	if (default_domain[0] != '\0')
		return default_domain;

	p = nis_local_directory();
	snprintf(default_domain, sizeof default_domain, "%s", p);
	return default_domain;
}

#endif /* NISPLUS */
/*
**  LDAP Modules
*/

/*
**  LDAPMAP_DEQUOTE - helper routine for ldapmap_parseargs
*/

#if defined(LDAPMAP) || defined(PH_MAP)

# ifdef PH_MAP
#  define ph_map_dequote ldapmap_dequote
# endif /* PH_MAP */

char *
ldapmap_dequote(str)
	char *str;
{
	char *p;
	char *start;

	if (str == NULL)
		return NULL;

	p = str;
	if (*p == '"')
	{
		/* Should probably swallow initial whitespace here */
		start = ++p;
	}
	else
		return str;
	while (*p != '"' && *p != '\0')
		p++;
	if (*p != '\0')
		*p = '\0';
	return start;
}
#endif /* defined(LDAPMAP) || defined(PH_MAP) */

#ifdef LDAPMAP

LDAPMAP_STRUCT *LDAPDefaults = NULL;

/*
**  LDAPMAP_OPEN -- open LDAP map
**
**	Connect to the LDAP server.  Re-use existing connections since a
**	single server connection to a host (with the same host, port,
**	bind DN, and secret) can answer queries for multiple maps.
*/

bool
ldapmap_open(map, mode)
	MAP *map;
	int mode;
{
	LDAPMAP_STRUCT *lmap;
	STAB *s;

	if (tTd(38, 2))
		dprintf("ldapmap_open(%s, %d): ", map->map_mname, mode);

	mode &= O_ACCMODE;

	/* sendmail doesn't have the ability to write to LDAP (yet) */
	if (mode != O_RDONLY)
	{
		/* issue a pseudo-error message */
# ifdef ENOSYS
		errno = ENOSYS;
# else /* ENOSYS */
#  ifdef EFTYPE
		errno = EFTYPE;
#  else /* EFTYPE */
		errno = ENXIO;
#  endif /* EFTYPE */
# endif /* ENOSYS */
		return FALSE;
	}

	/* Comma separate if used as an alias file */
	if (map->map_coldelim == '\0' && bitset(MF_ALIAS, map->map_mflags))
		map->map_coldelim = ',';

	lmap = (LDAPMAP_STRUCT *) map->map_db1;

	s = ldapmap_findconn(lmap);
	if (s->s_ldap != NULL)
	{
		/* Already have a connection open to this LDAP server */
		lmap->ldap_ld = s->s_ldap;
		if (tTd(38, 2))
			dprintf("using cached connection\n");
		return TRUE;
	}

	if (tTd(38, 2))
		dprintf("opening new connection\n");

	/* No connection yet, connect */
	if (!ldapmap_start(map))
		return FALSE;

	/* Save connection for reuse */
	s->s_ldap = lmap->ldap_ld;
	return TRUE;
}

/*
**  LDAPMAP_START -- actually connect to an LDAP server
**
**	Parameters:
**		map -- the map being opened.
**
**	Returns:
**		TRUE if connection is successful, FALSE otherwise.
**
**	Side Effects:
**		Populates lmap->ldap_ld.
*/

static

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -