2010-05-11 07:35:43 +02:00
/*
Unix SMB / CIFS implementation .
Manually parsed structures found in DNSP
Copyright ( C ) Andrew Tridgell 2010
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include "librpc/gen_ndr/ndr_dnsp.h"
/*
print a dnsp_name
*/
_PUBLIC_ void ndr_print_dnsp_name ( struct ndr_print * ndr , const char * name ,
const char * dns_name )
{
ndr - > print ( ndr , " %-25s: %s " , name , dns_name ) ;
}
/*
pull a dnsp_name
*/
_PUBLIC_ enum ndr_err_code ndr_pull_dnsp_name ( struct ndr_pull * ndr , int ndr_flags , const char * * name )
{
2010-12-21 11:59:54 +11:00
uint8_t len , count , termination ;
2010-05-11 07:35:43 +02:00
int i ;
2010-12-21 11:59:54 +11:00
uint32_t total_len , raw_offset ;
2010-05-11 07:35:43 +02:00
char * ret ;
NDR_CHECK ( ndr_pull_uint8 ( ndr , ndr_flags , & len ) ) ;
NDR_CHECK ( ndr_pull_uint8 ( ndr , ndr_flags , & count ) ) ;
2010-12-21 11:59:54 +11:00
raw_offset = ndr - > offset ;
2010-05-11 07:35:43 +02:00
ret = talloc_strdup ( ndr - > current_mem_ctx , " " ) ;
if ( ! ret ) {
2012-02-28 14:58:16 +11:00
return ndr_pull_error ( ndr , NDR_ERR_ALLOC , " Failed to pull dnsp_name " ) ;
2010-05-11 07:35:43 +02:00
}
total_len = 1 ;
for ( i = 0 ; i < count ; i + + ) {
uint8_t sublen , newlen ;
NDR_CHECK ( ndr_pull_uint8 ( ndr , ndr_flags , & sublen ) ) ;
newlen = total_len + sublen ;
if ( i ! = count - 1 ) {
newlen + + ; /* for the '.' */
}
ret = talloc_realloc ( ndr - > current_mem_ctx , ret , char , newlen ) ;
if ( ! ret ) {
2012-02-28 14:58:16 +11:00
return ndr_pull_error ( ndr , NDR_ERR_ALLOC , " Failed to pull dnsp_name " ) ;
2010-05-11 07:35:43 +02:00
}
NDR_CHECK ( ndr_pull_bytes ( ndr , ( uint8_t * ) & ret [ total_len - 1 ] , sublen ) ) ;
if ( i ! = count - 1 ) {
ret [ newlen - 2 ] = ' . ' ;
}
ret [ newlen - 1 ] = 0 ;
total_len = newlen ;
}
2010-12-21 11:59:54 +11:00
NDR_CHECK ( ndr_pull_uint8 ( ndr , ndr_flags , & termination ) ) ;
if ( termination ! = 0 ) {
2012-02-28 14:58:16 +11:00
return ndr_pull_error ( ndr , NDR_ERR_ALLOC , " Failed to pull dnsp_name - not NUL terminated " ) ;
2010-12-21 11:59:54 +11:00
}
if ( ndr - > offset > raw_offset + len ) {
2012-02-28 14:58:16 +11:00
return ndr_pull_error ( ndr , NDR_ERR_ALLOC , " Failed to pull dnsp_name - overrun by %u bytes " ,
2010-12-21 11:59:54 +11:00
ndr - > offset - ( raw_offset + len ) ) ;
}
/* there could be additional pad bytes */
while ( ndr - > offset < raw_offset + len ) {
uint8_t pad ;
NDR_CHECK ( ndr_pull_uint8 ( ndr , ndr_flags , & pad ) ) ;
}
2010-05-11 07:35:43 +02:00
( * name ) = ret ;
return NDR_ERR_SUCCESS ;
}
enum ndr_err_code ndr_push_dnsp_name ( struct ndr_push * ndr , int ndr_flags , const char * name )
{
int count , total_len , i ;
2010-12-15 23:52:32 +11:00
2010-05-11 07:35:43 +02:00
/* count the dots */
for ( count = i = 0 ; name [ i ] ; i + + ) {
if ( name [ i ] = = ' . ' ) count + + ;
}
2010-12-21 20:52:24 +11:00
total_len = strlen ( name ) + 1 ;
/* cope with names ending in '.' */
if ( name [ strlen ( name ) - 1 ] ! = ' . ' ) {
total_len + + ;
count + + ;
}
2010-05-11 07:35:43 +02:00
if ( total_len > 255 | | count > 255 ) {
return ndr_push_error ( ndr , NDR_ERR_BUFSIZE ,
" dns_name of length %d larger than 255 " , total_len ) ;
}
NDR_CHECK ( ndr_push_uint8 ( ndr , ndr_flags , ( uint8_t ) total_len ) ) ;
NDR_CHECK ( ndr_push_uint8 ( ndr , ndr_flags , ( uint8_t ) count ) ) ;
for ( i = 0 ; i < count ; i + + ) {
const char * p = strchr ( name , ' . ' ) ;
size_t sublen = p ? ( p - name ) : strlen ( name ) ;
NDR_CHECK ( ndr_push_uint8 ( ndr , ndr_flags , ( uint8_t ) sublen ) ) ;
NDR_CHECK ( ndr_push_bytes ( ndr , ( const uint8_t * ) name , sublen ) ) ;
name + = sublen + 1 ;
}
2010-12-15 23:52:32 +11:00
NDR_CHECK ( ndr_push_uint8 ( ndr , ndr_flags , 0 ) ) ;
2010-05-11 07:35:43 +02:00
return NDR_ERR_SUCCESS ;
}
2010-08-13 11:09:09 +02:00
/*
print a dnsp_string
*/
_PUBLIC_ void ndr_print_dnsp_string ( struct ndr_print * ndr , const char * name ,
const char * dns_string )
{
ndr - > print ( ndr , " %-25s: %s " , name , dns_string ) ;
}
/*
pull a dnsp_string
*/
_PUBLIC_ enum ndr_err_code ndr_pull_dnsp_string ( struct ndr_pull * ndr , int ndr_flags , const char * * string )
{
uint8_t len ;
char * ret ;
NDR_CHECK ( ndr_pull_uint8 ( ndr , ndr_flags , & len ) ) ;
2013-10-13 21:39:51 -07:00
ret = talloc_zero_array ( ndr - > current_mem_ctx , char , len + 1 ) ;
2010-08-13 11:09:09 +02:00
if ( ! ret ) {
2012-02-28 14:58:16 +11:00
return ndr_pull_error ( ndr , NDR_ERR_ALLOC , " Failed to pull dnsp_string " ) ;
2010-08-13 11:09:09 +02:00
}
2013-10-13 21:39:51 -07:00
NDR_CHECK ( ndr_pull_bytes ( ndr , ( uint8_t * ) ret , len ) ) ;
2010-08-13 11:09:09 +02:00
( * string ) = ret ;
NDR_PULL_ALIGN ( ndr , 1 ) ;
return NDR_ERR_SUCCESS ;
}
enum ndr_err_code ndr_push_dnsp_string ( struct ndr_push * ndr , int ndr_flags , const char * string )
{
int total_len ;
2012-02-28 13:58:48 +11:00
total_len = strlen ( string ) ;
2010-08-13 11:09:09 +02:00
if ( total_len > 255 ) {
return ndr_push_error ( ndr , NDR_ERR_BUFSIZE ,
" dns_name of length %d larger than 255 " , total_len ) ;
}
NDR_CHECK ( ndr_push_uint8 ( ndr , ndr_flags , ( uint8_t ) total_len ) ) ;
2012-02-28 13:58:48 +11:00
NDR_CHECK ( ndr_push_bytes ( ndr , ( const uint8_t * ) string , total_len ) ) ;
2010-08-13 11:09:09 +02:00
return NDR_ERR_SUCCESS ;
}
2012-02-28 15:07:10 +11:00
/*
* print a dnsp_string_list
*/
_PUBLIC_ void ndr_print_dnsp_string_list ( struct ndr_print * ndr , const char * name ,
const struct dnsp_string_list * list )
{
uint32_t i ;
ndr - > no_newline = true ;
for ( i = 0 ; i < ndr - > depth ; i + + ) {
ndr - > print ( ndr , " " ) ;
}
ndr - > print ( ndr , " %-25s: " , name ) ;
for ( i = 0 ; i < list - > count ; i + + ) {
ndr - > print ( ndr , " \" %s \" " , list - > str [ i ] ) ;
}
ndr - > print ( ndr , " \n " ) ;
ndr - > no_newline = false ;
}
/*
* pull a dnsp_string_list
*/
_PUBLIC_ enum ndr_err_code ndr_pull_dnsp_string_list ( struct ndr_pull * ndr , int ndr_flags , struct dnsp_string_list * list )
{
list - > count = 0 ;
2012-05-30 21:01:33 +10:00
list - > str = talloc_array ( ndr - > current_mem_ctx , const char * ,
list - > count ) ;
2012-02-28 15:07:10 +11:00
if ( ! list - > str ) {
return ndr_pull_error ( ndr , NDR_ERR_ALLOC , " Failed to pull dnsp_string_list " ) ;
}
while ( ndr - > offset < ndr - > data_size ) {
2012-05-30 21:01:33 +10:00
list - > str = talloc_realloc ( ndr - > current_mem_ctx , list - > str ,
const char * , list - > count + 1 ) ;
2012-02-28 15:07:10 +11:00
if ( ! list - > str ) {
return ndr_pull_error ( ndr , NDR_ERR_ALLOC , " Failed to pull dnsp_string_list " ) ;
}
NDR_CHECK ( ndr_pull_dnsp_string ( ndr , ndr_flags , & list - > str [ list - > count ] ) ) ;
list - > count + + ;
}
return NDR_ERR_SUCCESS ;
}
enum ndr_err_code ndr_push_dnsp_string_list ( struct ndr_push * ndr , int ndr_flags , const struct dnsp_string_list * list )
{
uint8_t i ;
for ( i = 0 ; i < list - > count ; i + + ) {
NDR_CHECK ( ndr_push_dnsp_string ( ndr , ndr_flags , list - > str [ i ] ) ) ;
}
return NDR_ERR_SUCCESS ;
}
2015-08-07 11:36:47 +02:00
enum ndr_err_code ndr_dnsp_string_list_copy ( TALLOC_CTX * mem_ctx ,
const struct dnsp_string_list * src ,
struct dnsp_string_list * dst )
{
size_t i ;
dst - > count = 0 ;
dst - > str = talloc_zero_array ( mem_ctx , const char * , src - > count ) ;
if ( dst - > str = = NULL ) {
return NDR_ERR_ALLOC ;
}
for ( i = 0 ; i < src - > count ; i + + ) {
dst - > str [ i ] = talloc_strdup ( dst - > str , src - > str [ i ] ) ;
if ( dst - > str [ i ] = = NULL ) {
TALLOC_FREE ( dst - > str ) ;
return NDR_ERR_ALLOC ;
}
}
dst - > count = src - > count ;
return NDR_ERR_SUCCESS ;
}