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

📄 hba.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 2 页
字号:
	{		snprintf(PQerrormsg, ERROR_MSG_LENGTH,			 "Failed to create socket on which to talk to Ident server. "				 "socket() returned errno = %s (%d)\n",				 strerror(errno), errno);		fputs(PQerrormsg, stderr);		pqdebug("%s", PQerrormsg);	}	else	{		struct sockaddr_in ident_server;		struct sockaddr_in la;		/*		 * Socket address of Ident server on the system from which client		 * is attempting to connect to us.		 */		ident_server.sin_family = AF_INET;		ident_server.sin_port = htons(IDENT_PORT);		ident_server.sin_addr = remote_ip_addr;		/*		 * Bind to the address which the client originally contacted,		 * otherwise the ident server won't be able to match up the right		 * connection. This is necessary if the PostgreSQL server is		 * running on an IP alias.		 */		memset(&la, 0, sizeof(la));		la.sin_family = AF_INET;		la.sin_addr = local_ip_addr;		rc = bind(sock_fd, (struct sockaddr *) & la, sizeof(la));		if (rc == 0)		{			rc = connect(sock_fd,			   (struct sockaddr *) & ident_server, sizeof(ident_server));		}		if (rc != 0)		{			snprintf(PQerrormsg, ERROR_MSG_LENGTH,				"Unable to connect to Ident server on the host which is "					 "trying to connect to Postgres "					 "(IP address %s, Port %d). "					 "errno = %s (%d)\n",					 inet_ntoa(remote_ip_addr), IDENT_PORT, strerror(errno), errno);			fputs(PQerrormsg, stderr);			pqdebug("%s", PQerrormsg);			*ident_failed = true;		}		else		{			char		ident_query[80];			/* The query we send to the Ident server */			snprintf(ident_query, 80, "%d,%d\n",					 ntohs(remote_port), ntohs(local_port));			rc = send(sock_fd, ident_query, strlen(ident_query), 0);			if (rc < 0)			{				snprintf(PQerrormsg, ERROR_MSG_LENGTH,						 "Unable to send query to Ident server on the host which is "					  "trying to connect to Postgres (Host %s, Port %d),"						 "even though we successfully connected to it.  "						 "errno = %s (%d)\n",						 inet_ntoa(remote_ip_addr), IDENT_PORT, strerror(errno), errno);				fputs(PQerrormsg, stderr);				pqdebug("%s", PQerrormsg);				*ident_failed = true;			}			else			{				char		ident_response[80 + IDENT_USERNAME_MAX];				rc = recv(sock_fd, ident_response, sizeof(ident_response) - 1, 0);				if (rc < 0)				{					snprintf(PQerrormsg, ERROR_MSG_LENGTH,						  "Unable to receive response from Ident server "							 "on the host which is "					  "trying to connect to Postgres (Host %s, Port %d),"					"even though we successfully sent our query to it.  "							 "errno = %s (%d)\n",							 inet_ntoa(remote_ip_addr), IDENT_PORT,							 strerror(errno), errno);					fputs(PQerrormsg, stderr);					pqdebug("%s", PQerrormsg);					*ident_failed = true;				}				else				{					bool		error;	/* response from Ident is garbage. */					ident_response[rc] = '\0';					interpret_ident_response(ident_response, &error, ident_username);					*ident_failed = error;				}			}			close(sock_fd);		}	}}static voidparse_map_record(FILE *file,				 char *file_map, char *file_pguser, char *file_iuser){/*---------------------------------------------------------------------------  Take the noncomment line which is next on file "file" and interpret  it as a line in a usermap file.  Specifically, return the first  3 tokens as file_map, file_iuser, and file_pguser, respectively.	If  there are fewer than 3 tokens, return null strings for the missing  ones.---------------------------------------------------------------------------*/	char		buf[MAX_TOKEN];	/* A token read from the file */	/* Set defaults in case fields not in file */	file_map[0] = '\0';	file_pguser[0] = '\0';	file_iuser[0] = '\0';	next_token(file, buf, sizeof(buf));	if (buf[0] != '\0')	{		strcpy(file_map, buf);		next_token(file, buf, sizeof(buf));		if (buf[0] != '\0')		{			strcpy(file_iuser, buf);			next_token(file, buf, sizeof(buf));			if (buf[0] != '\0')			{				strcpy(file_pguser, buf);				read_through_eol(file);				return;			}		}		snprintf(PQerrormsg, ERROR_MSG_LENGTH,				 "Incomplete line in pg_ident: %s", file_map);		fputs(PQerrormsg, stderr);		pqdebug("%s", PQerrormsg);	}}static voidverify_against_open_usermap(FILE *file,							const char *pguser,							const char *ident_username,							const char *usermap_name,							bool *checks_out_p){/*--------------------------------------------------------------------------  This function does the same thing as verify_against_usermap,  only with the config file already open on stream descriptor "file".---------------------------------------------------------------------------*/	bool		match;			/* We found a matching entry in the map								 * file */	bool		eof;			/* We've reached the end of the file we're								 * reading */	match = false;				/* initial value */	eof = false;				/* initial value */	while (!eof && !match)	{		/* Process a line from the map file */		int			c;			/* a character read from the file */		c = getc(file);		ungetc(c, file);		if (c == EOF)			eof = true;		else		{			if (c == '#')				read_through_eol(file);			else			{				/* The following are fields read from a record of the file */				char		file_map[MAX_TOKEN + 1];				char		file_pguser[MAX_TOKEN + 1];				char		file_iuser[MAX_TOKEN + 1];				parse_map_record(file, file_map, file_pguser, file_iuser);				if (strcmp(file_map, usermap_name) == 0 &&					strcmp(file_pguser, pguser) == 0 &&					strcmp(file_iuser, ident_username) == 0)					match = true;			}		}	}	*checks_out_p = match;}static voidverify_against_usermap(const char *pguser,					   const char *ident_username,					   const char *usermap_name,					   bool *checks_out_p){/*--------------------------------------------------------------------------  See if the user with ident username "ident_username" is allowed to act  as Postgres user "pguser" according to usermap "usermap_name".   Look  it up in the usermap file.  Special case: For usermap "sameuser", don't look in the usermap  file.  That's an implied map where "pguser" must be identical to  "ident_username" in order to be authorized.  Iff authorized, return *checks_out_p == true.--------------------------------------------------------------------------*/	if (usermap_name[0] == '\0')	{		*checks_out_p = false;		snprintf(PQerrormsg, ERROR_MSG_LENGTH,			   "verify_against_usermap: hba configuration file does not "		   "have the usermap field filled in in the entry that pertains "		  "to this connection.  That field is essential for Ident-based "				 "authentication.\n");		fputs(PQerrormsg, stderr);		pqdebug("%s", PQerrormsg);	}	else if (strcmp(usermap_name, "sameuser") == 0)	{		if (strcmp(ident_username, pguser) == 0)			*checks_out_p = true;		else			*checks_out_p = false;	}	else	{		FILE	   *file;		/* The map file we have to read */		char	   *map_file;	/* The name of the map file we have to								 * read */		int			bufsize;		/* put together the full pathname to the map file */		bufsize = (strlen(DataDir) + strlen(USERMAP_FILE) + 2) * sizeof(char);		map_file = (char *) palloc(bufsize);		snprintf(map_file, bufsize, "%s/%s", DataDir, USERMAP_FILE);#ifndef __CYGWIN32__		file = AllocateFile(map_file, "r");#else		file = AllocateFile(map_file, "rb");#endif		if (file == NULL)		{			/* The open of the map file failed.  */			*checks_out_p = false;			snprintf(PQerrormsg, ERROR_MSG_LENGTH,				  "verify_against_usermap: usermap file for Ident-based "					 "authentication "				"does not exist or permissions are not setup correctly! "					 "Unable to open file \"%s\".\n",					 map_file);			fputs(PQerrormsg, stderr);			pqdebug("%s", PQerrormsg);		}		else		{			verify_against_open_usermap(file,									pguser, ident_username, usermap_name,										checks_out_p);			FreeFile(file);		}		pfree(map_file);	}}intauthident(struct sockaddr_in * raddr, struct sockaddr_in * laddr,		  const char *postgres_username,		  const char *auth_arg){/*---------------------------------------------------------------------------  Talk to the ident server on the remote host and find out who owns the  connection described by "port".  Then look in the usermap file under  the usermap *auth_arg and see if that user is equivalent to  Postgres user *user.  Return STATUS_OK if yes.---------------------------------------------------------------------------*/	bool		checks_out;	bool		ident_failed;	/* We were unable to get ident to give us a username */	char		ident_username[IDENT_USERNAME_MAX + 1];	/* The username returned by ident */	ident(raddr->sin_addr, laddr->sin_addr,		  raddr->sin_port, laddr->sin_port,		  &ident_failed, ident_username);	if (ident_failed)		return STATUS_ERROR;	verify_against_usermap(postgres_username, ident_username, auth_arg,						   &checks_out);	return checks_out ? STATUS_OK : STATUS_ERROR;}#ifdef CYR_RECODE#define CHARSET_FILE "charset.conf"#define MAX_CHARSETS   10#define KEY_HOST	   1#define KEY_BASE	   2#define KEY_TABLE	   3struct CharsetItem{	char		Orig[MAX_TOKEN];	char		Dest[MAX_TOKEN];	char		Table[MAX_TOKEN];};intInRange(char *buf, int host){	int			valid,				i,				FromAddr,				ToAddr,				tmp;	struct in_addr file_ip_addr;	char	   *p;	unsigned int one = 0x80000000,				NetMask = 0;	unsigned char mask;	p = strchr(buf, '/');	if (p)	{		*p++ = '\0';		valid = inet_aton(buf, &file_ip_addr);		if (valid)		{			mask = strtoul(p, 0, 0);			FromAddr = ntohl(file_ip_addr.s_addr);			ToAddr = ntohl(file_ip_addr.s_addr);			for (i = 0; i < mask; i++)			{				NetMask |= one;				one >>= 1;			}			FromAddr &= NetMask;			ToAddr = ToAddr | ~NetMask;			tmp = ntohl(host);			return ((unsigned) tmp >= (unsigned) FromAddr &&					(unsigned) tmp <= (unsigned) ToAddr);		}	}	else	{		p = strchr(buf, '-');		if (p)		{			*p++ = '\0';			valid = inet_aton(buf, &file_ip_addr);			if (valid)			{				FromAddr = ntohl(file_ip_addr.s_addr);				valid = inet_aton(p, &file_ip_addr);				if (valid)				{					ToAddr = ntohl(file_ip_addr.s_addr);					tmp = ntohl(host);					return ((unsigned) tmp >= (unsigned) FromAddr &&							(unsigned) tmp <= (unsigned) ToAddr);				}			}		}		else		{			valid = inet_aton(buf, &file_ip_addr);			if (valid)			{				FromAddr = file_ip_addr.s_addr;				return (unsigned) FromAddr == (unsigned) host;			}		}	}	return false;}voidGetCharSetByHost(char *TableName, int host, const char *DataDir){	FILE	   *file;	char		buf[MAX_TOKEN],				BaseCharset[MAX_TOKEN],				OrigCharset[MAX_TOKEN],				DestCharset[MAX_TOKEN],				HostCharset[MAX_TOKEN],				c,				eof = false,			   *map_file;	int			key = 0,				ChIndex = 0,				i,				bufsize;	struct CharsetItem *ChArray[MAX_CHARSETS];	*TableName = '\0';	bufsize = (strlen(DataDir) + strlen(CHARSET_FILE) + 2) * sizeof(char);	map_file = (char *) palloc(bufsize);	snprintf(map_file, bufsize, "%s/%s", DataDir, CHARSET_FILE);#ifndef __CYGWIN32__	file = AllocateFile(map_file, "r");#else	file = AllocateFile(map_file, "rb");#endif	if (file == NULL)		return;	while (!eof)	{		c = getc(file);		ungetc(c, file);		if (c == EOF)			eof = true;		else		{			if (c == '#')				read_through_eol(file);			else			{				/* Read the key */				next_token(file, buf, sizeof(buf));				if (buf[0] != '\0')				{					if (strcasecmp(buf, "HostCharset") == 0)						key = KEY_HOST;					if (strcasecmp(buf, "BaseCharset") == 0)						key = KEY_BASE;					if (strcasecmp(buf, "RecodeTable") == 0)						key = KEY_TABLE;					switch (key)					{						case KEY_HOST:							/* Read the host */							next_token(file, buf, sizeof(buf));							if (buf[0] != '\0')							{								if (InRange(buf, host))								{									/* Read the charset */									next_token(file, buf, sizeof(buf));									if (buf[0] != '\0')										strcpy(HostCharset, buf);								}							}							break;						case KEY_BASE:							/* Read the base charset */							next_token(file, buf, sizeof(buf));							if (buf[0] != '\0')								strcpy(BaseCharset, buf);							break;						case KEY_TABLE:							/* Read the original charset */							next_token(file, buf, sizeof(buf));							if (buf[0] != '\0')							{								strcpy(OrigCharset, buf);								/* Read the destination charset */								next_token(file, buf, sizeof(buf));								if (buf[0] != '\0')								{									strcpy(DestCharset, buf);									/* Read the table filename */									next_token(file, buf, sizeof(buf));									if (buf[0] != '\0')									{										ChArray[ChIndex] =											(struct CharsetItem *) palloc(sizeof(struct CharsetItem));										strcpy(ChArray[ChIndex]->Orig, OrigCharset);										strcpy(ChArray[ChIndex]->Dest, DestCharset);										strcpy(ChArray[ChIndex]->Table, buf);										ChIndex++;									}								}							}							break;					}					read_through_eol(file);				}			}		}	}	FreeFile(file);	pfree(map_file);	for (i = 0; i < ChIndex; i++)	{		if (!strcasecmp(BaseCharset, ChArray[i]->Orig) &&			!strcasecmp(HostCharset, ChArray[i]->Dest))			strncpy(TableName, ChArray[i]->Table, 79);		pfree((struct CharsetItem *) ChArray[i]);	}}#endifinthba_getauthmethod(SockAddr *raddr, char *user, char *database,				  char *auth_arg, UserAuth *auth_method){/*---------------------------------------------------------------------------  Determine what authentication method should be used when accessing database  "database" from frontend "raddr", user "user".  Return the method,  an optional argument, and STATUS_OK.  Note that STATUS_ERROR indicates a problem with the hba config file.  If the file is OK but does not contain any entry matching the request,  we return STATUS_OK and method = uaReject.----------------------------------------------------------------------------*/	bool		hba_ok = false;	find_hba_entry(raddr, user, database, &hba_ok, auth_method, auth_arg);	return hba_ok ? STATUS_OK : STATUS_ERROR;}

⌨️ 快捷键说明

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