PHP 3/4 NIS Function bug
| From: | Luca Tessitore | Date: | Thu, 24 Aug 2000 10:27:38 +0000 |
| Subject: | PHP 3/4 NIS Function bug | ||
| Groups: | php.dev | ||
| Request: | Send a blank email to php-dev+get-30491@lists.php.net to get a copy of this message | ||
Good morning,
I'm working with PHP in my univerity (Politecnico of Torino) since version 3.
I use NIS/YP function (implemente in PHP) and i found a bug (allready in
version 3).
BUG:
yp_next() does not return any data after calling yp_first().
REASON:
The php's function yp_first() return an associative array with this fields
array["key"] NIS TABLE KEY
array["value"] NIS TABLE ENTRY
We use array["key"] for call yp_next() and retrive other entries in nis table.
I examine your source code /ext/yp/yp.c and I see that you call the yp
functione definied in libnls.
I write a simple C program that dump the content of passwd nis table (I
attach to you)
This is a part of his output:
Key l.tessitore (27 - 11)
Value l.tessitore:XXXXXXXXXXXXX:1204:10:Luca
Tessitore:/export/home/l.tessitore:/usr/bin/bash (87)
108 46 116 101 115 115 105 116 111 114 101 0 10 0 35 0 0 0 1 0 0 0 1 0 0 0 15
Key f.serra (23 - 7)
Value f.serra:XXXXXXXXXXXXXX1202:10:Fabrizio
Serra:/export/home/f.serra:/usr/bin/bash (79)
102 46 115 101 114 114 97 0 10 0 35 0 0 0 1 0 0 0 2 0 0 0 11
The third line of any entry is the list of ascii code of every chars in
nis table's key:
how you can see there are many byte in this char vector.
The two number after the key are effective key lenght and the lenght
calculated with strlen function.
the yp_next() C's function work only the parameter inkey is exactly the
ones received with yp_first (in C library).
This is out implementation of yp_first & yp_next in php:
PHP_FUNCTION(yp_first) {
pval **domain, **map;
char *outval, *outkey;
int outvallen, outkeylen;
if((ZEND_NUM_ARGS() != 2) || zend_get_parameters_ex(2,&domain,&map)
== FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_string_ex(domain);
convert_to_string_ex(map);
if(yp_first((*domain)->value.str.val,(*map)->value.str.val,&outkey,&outkeyle
n,&outval,&outvallen)) {
RETURN_FALSE;
}
array_init(return_value);
add_assoc_string(return_value,"key",outkey,1);
add_assoc_string(return_value,"value",outval,1);
}
looking ad add_assoc_string function i see that it copy only the byte from
0 to strlen(outkey), in this way we lose a part of the key (every nis key
had a NULL at the end of the string followed by a \n and then from other
byte ... i don't know what'are they meaning!!)
So from this original key:
108 46 116 101 115 115 105 116 111 114 101 0 10 0 35 0 0 0 1 0 0 0 1 0 0 0 15
we obtain this key:
108 46 116 101 115 115 105 116 111 114 101 0
... for this reason the call to yp_next php's function (after yp_first)
fail !!!!!!!
SOLUTION:
I modify the code of yp_next and yp_first from your yp.c file, in this
manner (i attach the file for you):
/* {{{ proto array yp_first(string domain, string map)
Returns the first key as $var["key"] and the first line as $var["value"] */
PHP_FUNCTION(yp_first) {
pval **domain, **map;
char *outval, *outkey;
int outvallen, outkeylen;
if((ZEND_NUM_ARGS() != 2) ||
zend_get_parameters_ex(2,&domain,&map) == FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_string_ex(domain);
convert_to_string_ex(map);
if(yp_first((*domain)->value.str.val,(*map)->value.str.val,&outkey,&outkeyle
n,&outval,&outvallen)) {
RETURN_FALSE;
}
array_init(return_value);
add_assoc_stringl(return_value,"key",outkey,outkeylen,1); //
LOOK AT THIS LINE
add_assoc_string(return_value,"value",outval,1);
}
/* }}} */
Using the funciont add_assoc_stringl() we copy all byte in the key and not
only the byte until the first NULL char.
/* {{{ proto array yp_next(string domain, string map, string key)
Returns an array with $var[$key] and the the line as the value */
PHP_FUNCTION(yp_next) {
pval **domain, **map, **key;
char *outval, *outkey;
int outvallen, outkeylen;
int errorCode;
if((ZEND_NUM_ARGS() != 3) ||
zend_get_parameters_ex(3,&domain,&map,&key) == FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_string_ex(domain);
convert_to_string_ex(map);
convert_to_string_ex(key);
if((errorCode=yp_next((*domain)->value.str.val,(*map)->value.str.val,(*key)-
>value.str.val,((*key)->value.str.len),&outkey,
RETURN_FALSE;
}
array_init(return_value);
add_assoc_stringl(return_value,"key",outkey,outkeylen,1); //
LOOK AT THIS LINE
add_assoc_string(return_value,"value",outval,1);
}
In this funcion we copy all byte from key too, using add_assoc_stringl.
I think is better return an associative array (key,value) in this funcion
too.
This simple php example dump the content of passwd nis table.
<?php
header("Content-type: text/plain");
$domain = yp_get_default_domain();
if(!$domain) {
echo "Can't connect NIS domain server. Make sure <B>ypbind</B> is
running.\n";
exit();
}
echo "Default NIS domain is: $domain\n\n";
echo "Dump content of passws nis table\n";
echo "--------------------------------\n";
$entry = yp_first($domain, "passwd.byname");
if(!$entry) {
echo "Error readind from table passwd\n";
exit();
}
echo $entry["value"];
$currentKey=$entry["key"];
while ( ($entryNext=yp_next($domain,"passwd.byname",$currentKey)) ) {
$currentKey=$entryNext["key"];
echo $entryNext["value"];
}
echo "\nEnd of table\n";
?>
I hope it can be usefull for you!!!!!! :-)
Best regards Luca Tessitore
P.S.
Sorry for my english :-)
#include <
#include <