- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我在 centOS 虚拟机中有一个 ejabberd 15.03 服务器,我需要使用 php 针对 SQL 服务器实现外部身份验证方法。官方文档展示了一个php/mysql的例子 php/mysql external authentification
有没有办法把这个例子改成php/sqlserver和mysql_ping等函数
这是我写的一个例子,把它放在/opt/auth/下,并配置 ejabberd.yml 来执行作为外部身份验证。
$auth = new JabberAuth();
$auth->dbhost = "hostIP";
$auth->dbuser = "user";
$auth->dbpass = "pass";
$auth->dbbase = "databaseName";
$auth->play(); // We simply start process !
class JabberAuth {
var $dbhost;
var $dbuser;
var $dbpass;
var $dbbase;
var $debug = false; /* Debug mode */
var $debugfile = "/opt/auth/log/pipe-debug.log"; /* Debug output */
var $logging = false; /* Do we log requests ? */
var $logfile = "/opt/auth/log/pipe-log.log" ; /* Log file ... */
/*
* For both debug and logging, ejabberd have to be able to write.
*/
var $jabber_user; /* This is the jabber user passed to the script. filled by $this->command() */
var $jabber_pass; /* This is the jabber user password passed to the script. filled by $this->command() */
var $jabber_server; /* This is the jabber server passed to the script. filled by $this->command(). Useful for VirtualHosts */
var $jid; /* Simply the JID, if you need it, you have to fill. */
var $data; /* This is what SM component send to us. */
var $dateformat = "M d H:i:s"; /* Check date() for string format. */
var $command; /* This is the command sent ... */
var $mysock; /* MySQL connection ressource */
var $stdin; /* stdin file pointer */
var $stdout; /* stdout file pointer */
function JabberAuth()
{
@define_syslog_variables();
@openlog("pipe-auth", LOG_NDELAY, LOG_SYSLOG);
if($this->debug) {
@error_reporting(E_ALL);
@ini_set("log_errors", "1");
@ini_set("error_log", $this->debugfile);
}
$this->logg("Starting pipe-auth ..."); // We notice that it's starting ...
$this->openstd();
}
function stop()
{
$this->logg("Shutting down ..."); // Sorry, have to go ...
closelog();
$this->closestd(); // Simply close files
exit(0); // and exit cleanly
}
function openstd()
{
$this->stdout = @fopen("php://stdout", "w"); // We open STDOUT so we can read
$this->stdin = @fopen("php://stdin", "r"); // and STDIN so we can talk !
}
function readstdin()
{
$l = @fgets($this->stdin, 3); // We take the length of string
$length = @unpack("n", $l); // ejabberd give us something to play with ...
$len = $length["1"]; // and we now know how long to read.
if($len > 0) { // if not, we'll fill logfile ... and disk full is just funny once
$this->logg("Reading $len bytes ... "); // We notice ...
$data = @fgets($this->stdin, $len+1);
// $data = iconv("UTF-8", "ISO-8859-15", $data); // To be tested, not sure if still needed.
$this->data = $data; // We set what we got.
$this->logg("IN: ".$data);
}
}
function closestd()
{
@fclose($this->stdin); // We close everything ...
@fclose($this->stdout);
}
function out($message)
{
@fwrite($this->stdout, $message); // We reply ...
$dump = @unpack("nn", $message);
$dump = $dump["n"];
$this->logg("OUT: ". $dump);
}
function myalive()
{
if(!is_resource($this->mysock) || !@mysql_ping($this->mysock)) { // check if we have a MySQL connection and if it's valid.
$this->mysql(); // We try to reconnect if MySQL gone away ...
return @mysql_ping($this->mysock); // we simply try again, to be sure ...
} else {
return true; // so good !
}
}
function play()
{
do {
$this->readstdin(); // get data
$length = strlen($this->data); // compute data length
if($length > 0 ) { // for debug mainly ...
$this->logg("GO: ".$this->data);
$this->logg("data length is : ".$length);
}
$ret = $this->command(); // play with data !
$this->logg("RE: " . $ret); // this is what WE send.
$this->out($ret); // send what we reply.
$this->data = NULL; // more clean. ...
} while (true);
}
function command()
{
$data = $this->splitcomm(); // This is an array, where each node is part of what SM sent to us :
// 0 => the command,
// and the others are arguments .. e.g. : user, server, password ...
if($this->myalive()) { // Check we can play with MySQL
if(strlen($data[0]) > 0 ) {
$this->logg("Command was : ".$data[0]);
}
switch($data[0]) {
case "isuser": // this is the "isuser" command, used to check for user existance
$this->jabber_user = $data[1];
$parms = $data[1]; // only for logging purpose
$return = $this->checkuser();
break;
case "auth": // check login, password
$this->jabber_user = $data[1];
$this->jabber_pass = $data[3];
$parms = $data[1].":".$data[2].":".md5($data[3]); // only for logging purpose
$return = $this->checkpass();
break;
case "setpass":
$return = false; // We do not want jabber to be able to change password
break;
default:
$this->stop(); // if it's not something known, we have to leave.
// never had a problem with this using ejabberd, but might lead to problem ?
break;
}
$return = ($return) ? 1 : 0;
if(strlen($data[0]) > 0 && strlen($parms) > 0) {
$this->logg("Command : ".$data[0].":".$parms." ==> ".$return." ");
}
return @pack("nn", 2, $return);
} else {
// $this->prevenir(); // Maybe useful to tell somewhere there's a problem ...
return @pack("nn", 2, 0); // it's so bad.
}
}
function checkpass()
{
$hash=sha1($this->jabber_pass);
$query = mssql_query("SELECT [attribute] FROM [DatabaseName].[dbo].[table] where (S_USERNAME='$this->jabber_user') AND (SUBSTRING(S_PASSWORD,1,(LEN(S_PASSWORD)-3)))='$hash'");
// Check if there were any records
if (!mssql_num_rows($query)) {
return false;
} else {
return true;
}
}
function checkuser()
{
$query = mssql_query("SELECT [attribute] FROM [DatabaseName].[dbo].[table] where S_USERNAME='$this->jabber_user'");
// Check if there were any records
if (!mssql_num_rows($query)) {
return false;
} else {
return true;
}
}
function splitcomm() // simply split command and arugments into an array.
{
return explode(":", $this->data);
}
function mysql() // "MySQL abstraction", this opens a permanent MySQL connection, and fill the ressource
{
$this->mysock = @mssql_pconnect($this->dbhost, $this->dbuser, $this->dbpass);
echo '1';
var_dump($this->mysock);
@mssql_select_db($this->dbbase, $this->mysock);
$this->logg("MsSql :: ". (is_resource($this->mysock) ? "Connecté" : "Déconnecté"));
}
function logg($message) // pretty simple, using syslog.
// some says it doesn't work ? perhaps, but AFAIR, it was working.
{
if($this->logging) {
@syslog(LOG_INFO, $message);
}
}
}
这没有产生任何 php 错误。但是在 ejabberd.log 中我总是得到'extauth 脚本突然退出,原因是'正常''
这是 crash.log 中的崩溃报告
2015-04-01 17:44:12 =CRASH REPORT==== crasher: initial call: ejabberd_http:init/2 pid: <0.8779.0> registered_name: [] exception error: bad argument: [{extauth,call_port,2,[{file,"src/extauth.erl"},{line,99}]},{ejabberd_auth_external,check_password_extauth,3,[{file,"src/ejabberd_auth_external.erl"},{line,182}]},{ejabberd_auth_external,check_password_external_cache,3,[{file,"src/ejabberd_auth_external.erl"},{line,244}]},{ejabberd_auth,check_password_loop,2,[{file,"src/ejabberd_auth.erl"},{line,158}]},{ejabberd_auth,check_password,3,[{file,"src/ejabberd_auth.erl"},{line,106}]},{ejabberd_web_admin,get_auth_account,5,[{file,"src/ejabberd_web_admin.erl"},{line,266}]},{ejabberd_web_admin,process,2,[{file,"src/ejabberd_web_admin.erl"},{line,221}]},{ejabberd_http,process,5,[{file,"src/ejabberd_http.erl"},{line,359}]}] ancestors: [ejabberd_http_sup,ejabberd_sup,<0.37.0>] messages: [] links: [<0.327.0>,#Port<0.12042>] dictionary: [{random_seed,{2036,6729,29501}}] trap_exit: false status: running heap_size: 2586 stack_size: 27 reductions: 1244 neighbours: 2015-04-01 17:44:12 =SUPERVISOR REPORT==== Supervisor: {local,ejabberd_http_sup} Context: child_terminated Reason: badarg Offender: [{pid,<0.8779.0>},{name,undefined},{mfargs,{ejabberd_http,start_link,undefined}},{restart_type,temporary},{shutdown,1000},{child_type,worker}]
这似乎是配置错误。这是我添加到 ejabberd.yml 的内容
auth_method: external
extauth_program: "php -f /etc/ejabberd-15.03/auth_script.php"
extauth_cache: 600
extauth_instances: 3
最佳答案
我认为最新版本的 ejabberd 不支持 SQL-server。所以我最终转向支持许多数据库的 openfire。
关于php - ejabberd 外部认证 php sql server,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29370149/
SQL、PL-SQL 和 T-SQL 之间有什么区别? 谁能解释一下这三者之间的区别,并提供每一个的相关使用场景? 最佳答案 SQL 是一种对集合进行操作的查询语言。 它或多或少是标准化的,几乎所有关
这个问题已经有答案了: What is the difference between SQL, PL-SQL and T-SQL? (6 个回答) 已关闭 9 年前。 我对 SQL 的了解足以完成我的
我在数据库中有一个 USER 表。该表有一个 RegistrationDate 列,该列有一个默认约束为 GETDATE()。 使用 LINQ 时,我没有为 RegistrationDate 列提供任
我有一个可能属于以下类型的字符串 string expected result 15-th-rp 15 15/12-rp 12 15-12-th
很难说出这里问的是什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或言辞激烈,无法以目前的形式合理回答。如需帮助澄清此问题以便可以重新打开,visit the help center . 9年前关闭
我有一个存储过程(称为 sprocGetArticles),它从文章表中返回文章列表。这个存储过程没有任何参数。 用户可以对每篇文章发表评论,我将这些评论存储在由文章 ID 链接的评论表中。 有什么方
我目前正在做一个 *cough*Oracle*cough* 数据库主题。讲师介绍embedded SQL作为让其他语言(例如 C、C++)与(Oracle)数据库交互的方式。 我自己做了一些数据库工作
SQL Server 中 SQL 语句的最大长度是多少?这个长度是否取决于 SQL Server 的版本? 例如,在 DECLARE @SQLStatement NVARCHAR(MAX) = N'S
这个问题已经有答案了: Simple way to transpose columns and rows in SQL? (9 个回答) 已关闭 8 年前。 CallType
预先感谢您对此提供的任何帮助。 假设我有一个查询,可以比较跨年的数据,从某个任意年份开始,永无止境(进入 future ),每年同一时期直到最后一个完整的月份(其特点是一月数据永远不会显示至 2 月
我在数据库中有一个 USER 表。该表有一个 RegistrationDate 列,该列的默认约束为 GETDATE()。 使用 LINQ 时,我没有为 RegistrationDate 列提供任何数
下面是我试图用来检查存储过程是否不存在然后创建过程的 sql。它会抛出一个错误:Incorrect syntax near the keyword 'PROCEDURE' IF NOT EXISTS
我有一个同事声称动态 SQL 在许多情况下比静态 SQL 执行得更快,所以我经常看到 DSQL 到处都是。除了明显的缺点,比如在运行之前无法检测到错误并且更难阅读,这是否准确?当我问他为什么一直使用
来自 lobodava 的动态 SQL 查询是: declare @sql nvarchar(4000) = N';with cteColumnts (ORDINAL_POSITION, CO
使用 SQL Server 中的存储过程执行动态 SQL 命令的现实优点和缺点是什么 EXEC (@SQL) 对比 EXEC SP_EXECUTESQL @SQL ? 最佳答案 sp_executes
我有这个有效的 SQL 查询: select sum(dbos.Points) as Points, dboseasons.Year from dbo.StatLines dbos i
我正在调试一些构建成功运行的 SQL 命令的代码。 然而,在查询结束时,查询结果似乎被写入了一个文本文件。 完整的查询如下 echo SELECT DATE,DATETABLE,DATE,APPDAT
我有一些创建表的 .sql 文件(MS SQL 数据库): 表_1.sql: IF OBJECT_ID (N'my_schema.table1', N'U') IS NOT NULL DROP TAB
我写了下面的 SQL 存储过程,它一直给我错误@pid = SELECT MAX(... 整个过程是: Alter PROCEDURE insert_partyco @pname varchar(20
我在 SQL Server 2005 中有包含两列 Fruit 和 Color 的表,如下所示 Fruit Colour Apple Red Orange
我是一名优秀的程序员,十分优秀!