2007-11-09 13:50:14 +03:00
/*
Unix SMB / CIFS implementation .
UUID / GUID functions
Copyright ( C ) Theodore Ts ' o 1996 , 1997 ,
Copyright ( C ) Jim McDonough 2002.
Copyright ( C ) Andrew Tridgell 2003.
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/ndr/libndr.h"
/**
build a GUID from a string
*/
2008-11-10 03:40:31 +03:00
_PUBLIC_ NTSTATUS GUID_from_data_blob ( const DATA_BLOB * s , struct GUID * guid )
2007-11-09 13:50:14 +03:00
{
NTSTATUS status = NT_STATUS_INVALID_PARAMETER ;
uint32_t time_low ;
uint32_t time_mid , time_hi_and_version ;
uint32_t clock_seq [ 2 ] ;
uint32_t node [ 6 ] ;
int i ;
2008-11-10 03:40:31 +03:00
if ( s - > data = = NULL ) {
2007-11-09 13:50:14 +03:00
return NT_STATUS_INVALID_PARAMETER ;
}
2008-11-10 03:40:31 +03:00
if ( s - > length = = 36 & &
11 = = sscanf ( ( const char * ) s - > data ,
" %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x " ,
2007-11-09 13:50:14 +03:00
& time_low , & time_mid , & time_hi_and_version ,
& clock_seq [ 0 ] , & clock_seq [ 1 ] ,
& node [ 0 ] , & node [ 1 ] , & node [ 2 ] , & node [ 3 ] , & node [ 4 ] , & node [ 5 ] ) ) {
status = NT_STATUS_OK ;
2008-11-10 03:40:31 +03:00
} else if ( s - > length = = 38
& & 11 = = sscanf ( ( const char * ) s - > data ,
" {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x} " ,
& time_low , & time_mid , & time_hi_and_version ,
& clock_seq [ 0 ] , & clock_seq [ 1 ] ,
& node [ 0 ] , & node [ 1 ] , & node [ 2 ] , & node [ 3 ] , & node [ 4 ] , & node [ 5 ] ) ) {
2007-11-09 13:50:14 +03:00
status = NT_STATUS_OK ;
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
guid - > time_low = time_low ;
guid - > time_mid = time_mid ;
guid - > time_hi_and_version = time_hi_and_version ;
guid - > clock_seq [ 0 ] = clock_seq [ 0 ] ;
guid - > clock_seq [ 1 ] = clock_seq [ 1 ] ;
for ( i = 0 ; i < 6 ; i + + ) {
guid - > node [ i ] = node [ i ] ;
}
return NT_STATUS_OK ;
}
2008-11-10 03:40:31 +03:00
/**
build a GUID from a string
*/
_PUBLIC_ NTSTATUS GUID_from_string ( const char * s , struct GUID * guid )
{
DATA_BLOB blob = data_blob_string_const ( s ) ;
return GUID_from_data_blob ( & blob , guid ) ;
return NT_STATUS_OK ;
}
2007-11-09 13:50:14 +03:00
/**
build a GUID from a string
*/
_PUBLIC_ NTSTATUS NS_GUID_from_string ( const char * s , struct GUID * guid )
{
NTSTATUS status = NT_STATUS_INVALID_PARAMETER ;
uint32_t time_low ;
uint32_t time_mid , time_hi_and_version ;
uint32_t clock_seq [ 2 ] ;
uint32_t node [ 6 ] ;
int i ;
if ( s = = NULL ) {
return NT_STATUS_INVALID_PARAMETER ;
}
if ( 11 = = sscanf ( s , " %08x-%04x%04x-%02x%02x%02x%02x-%02x%02x%02x%02x " ,
& time_low , & time_mid , & time_hi_and_version ,
& clock_seq [ 0 ] , & clock_seq [ 1 ] ,
& node [ 0 ] , & node [ 1 ] , & node [ 2 ] , & node [ 3 ] , & node [ 4 ] , & node [ 5 ] ) ) {
status = NT_STATUS_OK ;
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
guid - > time_low = time_low ;
guid - > time_mid = time_mid ;
guid - > time_hi_and_version = time_hi_and_version ;
guid - > clock_seq [ 0 ] = clock_seq [ 0 ] ;
guid - > clock_seq [ 1 ] = clock_seq [ 1 ] ;
for ( i = 0 ; i < 6 ; i + + ) {
guid - > node [ i ] = node [ i ] ;
}
return NT_STATUS_OK ;
}
/**
* generate a random GUID
*/
2008-10-13 17:01:28 +04:00
_PUBLIC_ struct GUID GUID_random ( void )
2007-11-09 13:50:14 +03:00
{
struct GUID guid ;
generate_random_buffer ( ( uint8_t * ) & guid , sizeof ( guid ) ) ;
guid . clock_seq [ 0 ] = ( guid . clock_seq [ 0 ] & 0x3F ) | 0x80 ;
guid . time_hi_and_version = ( guid . time_hi_and_version & 0x0FFF ) | 0x4000 ;
return guid ;
}
/**
* generate an empty GUID
*/
_PUBLIC_ struct GUID GUID_zero ( void )
{
struct GUID guid ;
ZERO_STRUCT ( guid ) ;
return guid ;
}
_PUBLIC_ bool GUID_all_zero ( const struct GUID * u )
{
if ( u - > time_low ! = 0 | |
u - > time_mid ! = 0 | |
u - > time_hi_and_version ! = 0 | |
u - > clock_seq [ 0 ] ! = 0 | |
u - > clock_seq [ 1 ] ! = 0 | |
! all_zero ( u - > node , 6 ) ) {
return false ;
}
return true ;
}
_PUBLIC_ bool GUID_equal ( const struct GUID * u1 , const struct GUID * u2 )
{
if ( u1 - > time_low ! = u2 - > time_low | |
u1 - > time_mid ! = u2 - > time_mid | |
u1 - > time_hi_and_version ! = u2 - > time_hi_and_version | |
u1 - > clock_seq [ 0 ] ! = u2 - > clock_seq [ 0 ] | |
u1 - > clock_seq [ 1 ] ! = u2 - > clock_seq [ 1 ] | |
memcmp ( u1 - > node , u2 - > node , 6 ) ! = 0 ) {
return false ;
}
return true ;
}
_PUBLIC_ int GUID_compare ( const struct GUID * u1 , const struct GUID * u2 )
{
if ( u1 - > time_low ! = u2 - > time_low ) {
return u1 - > time_low - u2 - > time_low ;
}
if ( u1 - > time_mid ! = u2 - > time_mid ) {
return u1 - > time_mid - u2 - > time_mid ;
}
if ( u1 - > time_hi_and_version ! = u2 - > time_hi_and_version ) {
return u1 - > time_hi_and_version - u2 - > time_hi_and_version ;
}
if ( u1 - > clock_seq [ 0 ] ! = u2 - > clock_seq [ 0 ] ) {
return u1 - > clock_seq [ 0 ] - u2 - > clock_seq [ 0 ] ;
}
if ( u1 - > clock_seq [ 1 ] ! = u2 - > clock_seq [ 1 ] ) {
return u1 - > clock_seq [ 1 ] - u2 - > clock_seq [ 1 ] ;
}
return memcmp ( u1 - > node , u2 - > node , 6 ) ;
}
/**
its useful to be able to display these in debugging messages
*/
_PUBLIC_ char * GUID_string ( TALLOC_CTX * mem_ctx , const struct GUID * guid )
{
return talloc_asprintf ( mem_ctx ,
" %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x " ,
guid - > time_low , guid - > time_mid ,
guid - > time_hi_and_version ,
guid - > clock_seq [ 0 ] ,
guid - > clock_seq [ 1 ] ,
guid - > node [ 0 ] , guid - > node [ 1 ] ,
guid - > node [ 2 ] , guid - > node [ 3 ] ,
guid - > node [ 4 ] , guid - > node [ 5 ] ) ;
}
_PUBLIC_ char * GUID_string2 ( TALLOC_CTX * mem_ctx , const struct GUID * guid )
{
char * ret , * s = GUID_string ( mem_ctx , guid ) ;
ret = talloc_asprintf ( mem_ctx , " {%s} " , s ) ;
talloc_free ( s ) ;
return ret ;
}
_PUBLIC_ char * NS_GUID_string ( TALLOC_CTX * mem_ctx , const struct GUID * guid )
{
return talloc_asprintf ( mem_ctx ,
" %08x-%04x%04x-%02x%02x%02x%02x-%02x%02x%02x%02x " ,
guid - > time_low , guid - > time_mid ,
guid - > time_hi_and_version ,
guid - > clock_seq [ 0 ] ,
guid - > clock_seq [ 1 ] ,
guid - > node [ 0 ] , guid - > node [ 1 ] ,
guid - > node [ 2 ] , guid - > node [ 3 ] ,
guid - > node [ 4 ] , guid - > node [ 5 ] ) ;
}
_PUBLIC_ bool policy_handle_empty ( struct policy_handle * h )
{
return ( h - > handle_type = = 0 & & GUID_all_zero ( & h - > uuid ) ) ;
}