2007-12-21 20:57:34 +03:00
/*
Unix SMB / CIFS implementation .
Winbind client API
Copyright ( C ) Gerald ( Jerry ) Carter 2007
2015-02-21 03:19:32 +03:00
Copyright ( C ) Matthew Newton 2015
2007-12-21 20:57:34 +03:00
This library is free software ; you can redistribute it and / or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation ; either
version 3 of the License , or ( at your option ) any later version .
This library 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
Library General Public License for more details .
You should have received a copy of the GNU Lesser General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
/* Required Headers */
2009-06-05 00:32:21 +04:00
# include "replace.h"
2007-12-21 20:57:34 +03:00
# include "libwbclient.h"
/* From wb_common.c */
2015-02-21 03:19:32 +03:00
struct winbindd_context ;
2015-01-24 02:58:53 +03:00
NSS_STATUS winbindd_request_response ( struct winbindd_context * wbctx ,
int req_type ,
2007-12-21 20:57:34 +03:00
struct winbindd_request * request ,
struct winbindd_response * response ) ;
2015-01-24 02:58:53 +03:00
NSS_STATUS winbindd_priv_request_response ( struct winbindd_context * wbctx ,
int req_type ,
2010-04-13 14:09:21 +04:00
struct winbindd_request * request ,
struct winbindd_response * response ) ;
2015-02-21 03:19:32 +03:00
struct winbindd_context * winbindd_ctx_create ( void ) ;
void winbindd_ctx_free ( struct winbindd_context * ctx ) ;
2015-02-23 02:31:48 +03:00
/* Global context used for non-Ctx functions */
static struct wbcContext wbcGlobalCtx = {
. winbindd_ctx = NULL ,
. pw_cache_size = 0 ,
. pw_cache_idx = 0 ,
. gr_cache_size = 0 ,
. gr_cache_idx = 0
} ;
2007-12-21 20:57:34 +03:00
2010-05-05 17:33:09 +04:00
/*
2007-12-21 20:57:34 +03:00
result = = NSS_STATUS_UNAVAIL : winbind not around
result = = NSS_STATUS_NOTFOUND : winbind around , but domain missing
Due to a bad API NSS_STATUS_NOTFOUND is returned both when winbind_off
and when winbind return WINBINDD_ERROR . So the semantics of this
routine depends on winbind_on . Grepping for winbind_off I just
found 3 places where winbind is turned off , and this does not conflict
( as far as I have seen ) with the callers of is_trusted_domains .
- - Volker
2010-05-05 17:33:09 +04:00
*/
2007-12-21 20:57:34 +03:00
2010-04-13 14:09:21 +04:00
static wbcErr wbcRequestResponseInt (
2015-01-24 03:30:00 +03:00
struct winbindd_context * wbctx ,
2010-04-13 14:09:21 +04:00
int cmd ,
struct winbindd_request * request ,
struct winbindd_response * response ,
2015-01-24 02:58:53 +03:00
NSS_STATUS ( * fn ) ( struct winbindd_context * wbctx , int req_type ,
2010-04-13 14:09:21 +04:00
struct winbindd_request * request ,
struct winbindd_response * response ) )
2007-12-21 20:57:34 +03:00
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
NSS_STATUS nss_status ;
2008-10-28 09:36:36 +03:00
/* for some calls the request and/or response can be NULL */
2007-12-21 20:57:34 +03:00
2015-01-24 03:30:00 +03:00
nss_status = fn ( wbctx , cmd , request , response ) ;
2007-12-21 20:57:34 +03:00
switch ( nss_status ) {
case NSS_STATUS_SUCCESS :
wbc_status = WBC_ERR_SUCCESS ;
break ;
case NSS_STATUS_UNAVAIL :
2008-01-19 13:08:49 +03:00
wbc_status = WBC_ERR_WINBIND_NOT_AVAILABLE ;
2007-12-21 20:57:34 +03:00
break ;
case NSS_STATUS_NOTFOUND :
2008-01-19 13:08:49 +03:00
wbc_status = WBC_ERR_DOMAIN_NOT_FOUND ;
2007-12-21 20:57:34 +03:00
break ;
default :
wbc_status = WBC_ERR_NSS_ERROR ;
break ;
}
return wbc_status ;
}
2010-05-05 17:33:09 +04:00
/**
* @ brief Wrapper around Winbind ' s send / receive API call
*
2015-01-24 03:30:00 +03:00
* @ param ctx Context
2010-05-05 17:33:09 +04:00
* @ param cmd Winbind command operation to perform
* @ param request Send structure
* @ param response Receive structure
*
* @ return # wbcErr
*/
2015-01-24 03:30:00 +03:00
wbcErr wbcRequestResponse ( struct wbcContext * ctx , int cmd ,
2010-04-13 14:09:21 +04:00
struct winbindd_request * request ,
struct winbindd_response * response )
{
2015-01-24 03:30:00 +03:00
struct winbindd_context * wbctx = NULL ;
if ( ctx ) {
wbctx = ctx - > winbindd_ctx ;
}
return wbcRequestResponseInt ( wbctx , cmd , request , response ,
2010-04-13 14:09:21 +04:00
winbindd_request_response ) ;
}
2015-01-24 03:30:00 +03:00
wbcErr wbcRequestResponsePriv ( struct wbcContext * ctx , int cmd ,
2010-04-13 14:09:21 +04:00
struct winbindd_request * request ,
struct winbindd_response * response )
{
2015-01-24 03:30:00 +03:00
struct winbindd_context * wbctx = NULL ;
if ( ctx ) {
wbctx = ctx - > winbindd_ctx ;
}
return wbcRequestResponseInt ( wbctx , cmd , request , response ,
2010-04-13 14:09:21 +04:00
winbindd_priv_request_response ) ;
}
2008-02-11 18:29:28 +03:00
/** @brief Translate an error value into a string
*
* @ param error
*
* @ return a pointer to a static string
* */
const char * wbcErrorString ( wbcErr error )
{
switch ( error ) {
case WBC_ERR_SUCCESS :
return " WBC_ERR_SUCCESS " ;
case WBC_ERR_NOT_IMPLEMENTED :
return " WBC_ERR_NOT_IMPLEMENTED " ;
case WBC_ERR_UNKNOWN_FAILURE :
return " WBC_ERR_UNKNOWN_FAILURE " ;
case WBC_ERR_NO_MEMORY :
return " WBC_ERR_NO_MEMORY " ;
case WBC_ERR_INVALID_SID :
return " WBC_ERR_INVALID_SID " ;
case WBC_ERR_INVALID_PARAM :
return " WBC_ERR_INVALID_PARAM " ;
case WBC_ERR_WINBIND_NOT_AVAILABLE :
return " WBC_ERR_WINBIND_NOT_AVAILABLE " ;
case WBC_ERR_DOMAIN_NOT_FOUND :
return " WBC_ERR_DOMAIN_NOT_FOUND " ;
2008-04-17 19:49:53 +04:00
case WBC_ERR_INVALID_RESPONSE :
return " WBC_ERR_INVALID_RESPONSE " ;
2008-02-11 18:29:28 +03:00
case WBC_ERR_NSS_ERROR :
return " WBC_ERR_NSS_ERROR " ;
2008-05-13 21:52:20 +04:00
case WBC_ERR_UNKNOWN_USER :
return " WBC_ERR_UNKNOWN_USER " ;
case WBC_ERR_UNKNOWN_GROUP :
return " WBC_ERR_UNKNOWN_GROUP " ;
2008-01-24 16:05:59 +03:00
case WBC_ERR_AUTH_ERROR :
return " WBC_ERR_AUTH_ERROR " ;
2008-08-15 04:00:46 +04:00
case WBC_ERR_PWD_CHANGE_FAILED :
return " WBC_ERR_PWD_CHANGE_FAILED " ;
2008-02-11 18:29:28 +03:00
}
return " unknown wbcErr value " ;
2008-04-09 20:20:07 +04:00
}
2008-02-11 18:29:28 +03:00
2010-04-07 00:10:22 +04:00
# define WBC_MAGIC (0x7a2b0e1e)
2010-09-16 14:11:47 +04:00
# define WBC_MAGIC_FREE (0x875634fe)
2010-04-07 00:10:22 +04:00
struct wbcMemPrefix {
uint32_t magic ;
void ( * destructor ) ( void * ptr ) ;
} ;
static size_t wbcPrefixLen ( void )
{
size_t result = sizeof ( struct wbcMemPrefix ) ;
return ( result + 15 ) & ~ 15 ;
}
static struct wbcMemPrefix * wbcMemToPrefix ( void * ptr )
{
return ( struct wbcMemPrefix * ) ( ( ( char * ) ptr ) - wbcPrefixLen ( ) ) ;
}
void * wbcAllocateMemory ( size_t nelem , size_t elsize ,
void ( * destructor ) ( void * ptr ) )
{
struct wbcMemPrefix * result ;
if ( nelem > = ( 2 < < 24 ) / elsize ) {
/* basic protection against integer wrap */
return NULL ;
}
result = ( struct wbcMemPrefix * ) calloc (
1 , nelem * elsize + wbcPrefixLen ( ) ) ;
if ( result = = NULL ) {
return NULL ;
}
result - > magic = WBC_MAGIC ;
result - > destructor = destructor ;
return ( ( char * ) result ) + wbcPrefixLen ( ) ;
}
2008-12-09 15:18:06 +03:00
/* Free library allocated memory */
2007-12-21 20:57:34 +03:00
void wbcFreeMemory ( void * p )
{
2010-04-07 00:10:22 +04:00
struct wbcMemPrefix * wbcMem ;
2007-12-21 20:57:34 +03:00
2010-04-07 00:10:22 +04:00
if ( p = = NULL ) {
return ;
}
wbcMem = wbcMemToPrefix ( p ) ;
if ( wbcMem - > magic ! = WBC_MAGIC ) {
return ;
}
2010-09-16 14:11:47 +04:00
/* paranoid check to ensure we don't double free */
wbcMem - > magic = WBC_MAGIC_FREE ;
2010-04-07 00:10:22 +04:00
if ( wbcMem - > destructor ! = NULL ) {
wbcMem - > destructor ( p ) ;
}
free ( wbcMem ) ;
2007-12-21 20:57:34 +03:00
return ;
}
2010-04-03 13:59:29 +04:00
char * wbcStrDup ( const char * str )
{
char * result ;
size_t len ;
len = strlen ( str ) ;
result = ( char * ) wbcAllocateMemory ( len + 1 , sizeof ( char ) , NULL ) ;
if ( result = = NULL ) {
return NULL ;
}
memcpy ( result , str , len + 1 ) ;
return result ;
}
2010-04-03 15:37:01 +04:00
static void wbcStringArrayDestructor ( void * ptr )
{
char * * p = ( char * * ) ptr ;
while ( * p ! = NULL ) {
free ( * p ) ;
p + = 1 ;
}
}
const char * * wbcAllocateStringArray ( int num_strings )
{
return ( const char * * ) wbcAllocateMemory (
num_strings + 1 , sizeof ( const char * ) ,
wbcStringArrayDestructor ) ;
}
2008-05-23 16:18:42 +04:00
wbcErr wbcLibraryDetails ( struct wbcLibraryDetails * * _details )
{
struct wbcLibraryDetails * info ;
2010-04-07 00:14:03 +04:00
info = ( struct wbcLibraryDetails * ) wbcAllocateMemory (
1 , sizeof ( struct wbcLibraryDetails ) , NULL ) ;
2010-01-23 21:26:51 +03:00
if ( info = = NULL ) {
return WBC_ERR_NO_MEMORY ;
}
2008-05-23 16:18:42 +04:00
info - > major_version = WBCLIENT_MAJOR_VERSION ;
info - > minor_version = WBCLIENT_MINOR_VERSION ;
2010-01-23 21:26:51 +03:00
info - > vendor_version = WBCLIENT_VENDOR_VERSION ;
2008-05-23 16:18:42 +04:00
* _details = info ;
2010-01-23 21:26:51 +03:00
return WBC_ERR_SUCCESS ;
2008-05-23 16:18:42 +04:00
}
2015-02-21 03:19:32 +03:00
/* Context handling functions */
static void wbcContextDestructor ( void * ptr )
{
struct wbcContext * ctx = ( struct wbcContext * ) ptr ;
winbindd_ctx_free ( ctx - > winbindd_ctx ) ;
}
struct wbcContext * wbcCtxCreate ( void )
{
struct wbcContext * ctx ;
struct winbindd_context * wbctx ;
ctx = ( struct wbcContext * ) wbcAllocateMemory (
1 , sizeof ( struct wbcContext ) , wbcContextDestructor ) ;
if ( ! ctx ) {
return NULL ;
}
wbctx = winbindd_ctx_create ( ) ;
if ( ! wbctx ) {
wbcFreeMemory ( ctx ) ;
return NULL ;
}
ctx - > winbindd_ctx = wbctx ;
return ctx ;
}
void wbcCtxFree ( struct wbcContext * ctx )
{
wbcFreeMemory ( ctx ) ;
}
2015-02-23 02:31:48 +03:00
struct wbcContext * wbcGetGlobalCtx ( void )
{
return & wbcGlobalCtx ;
}