2007-12-21 20:57:34 +03:00
/*
Unix SMB / CIFS implementation .
Winbind client API
Copyright ( C ) Gerald ( Jerry ) Carter 2007
2009-04-01 01:10:48 +04:00
Copyright ( C ) Kai Blin 2009
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"
2009-04-01 01:10:48 +04:00
struct wbc_sid_to_uid_state {
struct winbindd_request req ;
uid_t uid ;
} ;
static void wbcSidToUid_done ( struct tevent_req * subreq ) ;
/**
* @ brief Convert a Windows SID to a Unix uid , allocating an uid if needed
*
* @ param mem_ctx talloc context to allocate the request from
* @ param ev tevent context to use for async operation
* @ param wb_ctx winbind context to use
* @ param * sid pointer to the domain SID to be resolved
*
* @ return tevent_req on success , NULL on error
*/
struct tevent_req * wbcSidToUid_send ( TALLOC_CTX * mem_ctx ,
struct tevent_context * ev ,
struct wb_context * wb_ctx ,
const struct wbcDomainSid * sid )
{
struct tevent_req * req , * subreq ;
struct wbc_sid_to_uid_state * state ;
char * sid_string ;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
req = tevent_req_create ( mem_ctx , & state , struct wbc_sid_to_uid_state ) ;
if ( req = = NULL ) {
return NULL ;
}
ZERO_STRUCT ( state - > req ) ;
state - > req . cmd = WINBINDD_SID_TO_UID ;
wbc_status = wbcSidToString ( sid , & sid_string ) ;
if ( ! WBC_ERROR_IS_OK ( wbc_status ) ) {
return tevent_req_post ( req , ev ) ;
}
strncpy ( state - > req . data . sid , sid_string , sizeof ( state - > req . data . sid ) - 1 ) ;
wbcFreeMemory ( sid_string ) ;
subreq = wb_trans_send ( state , ev , wb_ctx , false , & state - > req ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
return tevent_req_post ( req , ev ) ;
}
tevent_req_set_callback ( subreq , wbcSidToUid_done , req ) ;
return req ;
}
static void wbcSidToUid_done ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct wbc_sid_to_uid_state * state = tevent_req_data (
req , struct wbc_sid_to_uid_state ) ;
struct winbindd_response * resp ;
wbcErr wbc_status ;
wbc_status = wb_trans_recv ( subreq , state , & resp ) ;
TALLOC_FREE ( subreq ) ;
if ( ! WBC_ERROR_IS_OK ( wbc_status ) ) {
tevent_req_error ( req , wbc_status ) ;
return ;
}
state - > uid = resp - > data . uid ;
TALLOC_FREE ( resp ) ;
tevent_req_done ( req ) ;
}
/**
* @ brief Receive a Unix uid mapped to a Windows SID
*
* @ param req tevent_req containing the request
* @ param * puid pointer to hold the resolved uid_t value
*
* @ return # wbcErr
*/
wbcErr wbcSidToUid_recv ( struct tevent_req * req , uid_t * puid )
{
struct wbc_sid_to_uid_state * state = tevent_req_data (
req , struct wbc_sid_to_uid_state ) ;
wbcErr wbc_status ;
if ( tevent_req_is_wbcerr ( req , & wbc_status ) ) {
tevent_req_received ( req ) ;
return wbc_status ;
}
* puid = state - > uid ;
tevent_req_received ( req ) ;
return WBC_ERR_SUCCESS ;
}
2008-12-09 15:18:06 +03:00
/* Convert a Windows SID to a Unix uid, allocating an uid if needed */
2007-12-21 20:57:34 +03:00
wbcErr wbcSidToUid ( const struct wbcDomainSid * sid , uid_t * puid )
{
struct winbindd_request request ;
struct winbindd_response response ;
char * sid_string = NULL ;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
if ( ! sid | | ! puid ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
/* Initialize request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
wbc_status = wbcSidToString ( sid , & sid_string ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
strncpy ( request . data . sid , sid_string , sizeof ( request . data . sid ) - 1 ) ;
wbcFreeMemory ( sid_string ) ;
/* Make request */
wbc_status = wbcRequestResponse ( WINBINDD_SID_TO_UID ,
& request ,
& response ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
* puid = response . data . uid ;
wbc_status = WBC_ERR_SUCCESS ;
done :
return wbc_status ;
}
2008-12-09 15:18:06 +03:00
/* Convert a Windows SID to a Unix uid if there already is a mapping */
2008-11-23 02:57:33 +03:00
wbcErr wbcQuerySidToUid ( const struct wbcDomainSid * sid ,
uid_t * puid )
{
return WBC_ERR_NOT_IMPLEMENTED ;
}
2009-04-02 11:57:40 +04:00
struct wbc_uid_to_sid_state {
struct winbindd_request req ;
struct wbcDomainSid * sid ;
} ;
static void wbcUidToSid_done ( struct tevent_req * subreq ) ;
/**
* @ brief Request a Windows SID for an Unix uid , allocating an SID if needed
*
* @ param mem_ctx talloc context to allocate the request from
* @ param ev tevent context to use for async operation
* @ param wb_ctx winbind context to use
* @ param uid uid to be resolved to a SID
*
* @ return tevent_req on success , NULL on error
*/
struct tevent_req * wbcUidToSid_send ( TALLOC_CTX * mem_ctx ,
struct tevent_context * ev ,
struct wb_context * wb_ctx ,
uid_t uid )
{
struct tevent_req * req , * subreq ;
struct wbc_uid_to_sid_state * state ;
req = tevent_req_create ( mem_ctx , & state , struct wbc_uid_to_sid_state ) ;
if ( req = = NULL ) {
return NULL ;
}
ZERO_STRUCT ( state - > req ) ;
state - > req . cmd = WINBINDD_UID_TO_SID ;
state - > req . data . uid = uid ;
subreq = wb_trans_send ( state , ev , wb_ctx , false , & state - > req ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
return tevent_req_post ( req , ev ) ;
}
tevent_req_set_callback ( subreq , wbcUidToSid_done , req ) ;
return req ;
}
static void wbcUidToSid_done ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct wbc_uid_to_sid_state * state = tevent_req_data (
req , struct wbc_uid_to_sid_state ) ;
struct winbindd_response * resp ;
wbcErr wbc_status ;
wbc_status = wb_trans_recv ( subreq , state , & resp ) ;
TALLOC_FREE ( subreq ) ;
if ( ! WBC_ERROR_IS_OK ( wbc_status ) ) {
tevent_req_error ( req , wbc_status ) ;
return ;
}
state - > sid = talloc ( state , struct wbcDomainSid ) ;
if ( state - > sid = = NULL ) {
TALLOC_FREE ( resp ) ;
tevent_req_error ( req , WBC_ERR_NO_MEMORY ) ;
return ;
}
wbc_status = wbcStringToSid ( resp - > data . sid . sid , state - > sid ) ;
TALLOC_FREE ( resp ) ;
if ( ! WBC_ERROR_IS_OK ( wbc_status ) ) {
tevent_req_error ( req , wbc_status ) ;
return ;
}
tevent_req_done ( req ) ;
}
/**
* @ brief Receive a Unix uid mapped to a Windows SID
*
* @ param req tevent_req containing the request
* @ param * psid pointer to hold the resolved SID
*
* @ return # wbcErr
*/
wbcErr wbcUidToSid_recv ( struct tevent_req * req , struct wbcDomainSid * psid )
{
struct wbc_uid_to_sid_state * state = tevent_req_data (
req , struct wbc_uid_to_sid_state ) ;
wbcErr wbc_status ;
if ( psid = = NULL ) {
tevent_req_received ( req ) ;
return WBC_ERR_INVALID_PARAM ;
}
if ( tevent_req_is_wbcerr ( req , & wbc_status ) ) {
tevent_req_received ( req ) ;
return wbc_status ;
}
memcpy ( psid , state - > sid , sizeof ( struct wbcDomainSid ) ) ;
tevent_req_received ( req ) ;
return WBC_ERR_SUCCESS ;
}
2008-12-09 15:18:06 +03:00
/* Convert a Unix uid to a Windows SID, allocating a SID if needed */
2007-12-21 20:57:34 +03:00
wbcErr wbcUidToSid ( uid_t uid , struct wbcDomainSid * sid )
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
struct winbindd_request request ;
struct winbindd_response response ;
if ( ! sid ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
/* Initialize request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
request . data . uid = uid ;
/* Make request */
wbc_status = wbcRequestResponse ( WINBINDD_UID_TO_SID ,
& request ,
& response ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
wbc_status = wbcStringToSid ( response . data . sid . sid , sid ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
done :
return wbc_status ;
}
2008-12-09 15:18:06 +03:00
/* Convert a Unix uid to a Windows SID if there already is a mapping */
2008-11-23 02:57:33 +03:00
wbcErr wbcQueryUidToSid ( uid_t uid ,
struct wbcDomainSid * sid )
{
return WBC_ERR_NOT_IMPLEMENTED ;
}
/** @brief Convert a Windows SID to a Unix gid, allocating a gid if needed
2007-12-21 20:57:34 +03:00
*
* @ param * sid Pointer to the domain SID to be resolved
* @ param * pgid Pointer to the resolved gid_t value
*
* @ return # wbcErr
*
* */
wbcErr wbcSidToGid ( const struct wbcDomainSid * sid , gid_t * pgid )
{
struct winbindd_request request ;
struct winbindd_response response ;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
char * sid_string = NULL ;
if ( ! sid | | ! pgid ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
/* Initialize request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
wbc_status = wbcSidToString ( sid , & sid_string ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
strncpy ( request . data . sid , sid_string , sizeof ( request . data . sid ) - 1 ) ;
wbcFreeMemory ( sid_string ) ;
/* Make request */
wbc_status = wbcRequestResponse ( WINBINDD_SID_TO_GID ,
& request ,
& response ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
* pgid = response . data . gid ;
wbc_status = WBC_ERR_SUCCESS ;
done :
return wbc_status ;
}
2008-12-09 15:18:06 +03:00
/* Convert a Windows SID to a Unix gid if there already is a mapping */
2008-11-23 02:57:33 +03:00
wbcErr wbcQuerySidToGid ( const struct wbcDomainSid * sid ,
gid_t * pgid )
{
return WBC_ERR_NOT_IMPLEMENTED ;
}
2008-12-09 15:18:06 +03:00
/* Convert a Unix gid to a Windows SID, allocating a SID if needed */
2007-12-21 20:57:34 +03:00
wbcErr wbcGidToSid ( gid_t gid , struct wbcDomainSid * sid )
{
struct winbindd_request request ;
struct winbindd_response response ;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
if ( ! sid ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
/* Initialize request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
request . data . gid = gid ;
/* Make request */
wbc_status = wbcRequestResponse ( WINBINDD_GID_TO_SID ,
& request ,
& response ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
wbc_status = wbcStringToSid ( response . data . sid . sid , sid ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
done :
return wbc_status ;
}
2008-12-09 15:18:06 +03:00
/* Convert a Unix gid to a Windows SID if there already is a mapping */
2008-11-23 02:57:33 +03:00
wbcErr wbcQueryGidToSid ( gid_t gid ,
struct wbcDomainSid * sid )
{
return WBC_ERR_NOT_IMPLEMENTED ;
}
2008-12-09 15:18:06 +03:00
/* Obtain a new uid from Winbind */
2007-12-21 20:57:34 +03:00
wbcErr wbcAllocateUid ( uid_t * puid )
{
struct winbindd_request request ;
struct winbindd_response response ;
2007-12-23 02:35:06 +03:00
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
2007-12-21 20:57:34 +03:00
if ( ! puid )
return WBC_ERR_INVALID_PARAM ;
/* Initialise request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
/* Make request */
2007-12-23 02:35:06 +03:00
wbc_status = wbcRequestResponse ( WINBINDD_ALLOCATE_UID ,
2007-12-21 20:57:34 +03:00
& request , & response ) ;
2007-12-23 02:35:06 +03:00
BAIL_ON_WBC_ERROR ( wbc_status ) ;
2007-12-21 20:57:34 +03:00
/* Copy out result */
* puid = response . data . uid ;
2007-12-23 02:35:06 +03:00
wbc_status = WBC_ERR_SUCCESS ;
done :
return wbc_status ;
2007-12-21 20:57:34 +03:00
}
2008-12-09 15:18:06 +03:00
/* Obtain a new gid from Winbind */
2008-04-06 13:27:36 +04:00
wbcErr wbcAllocateGid ( gid_t * pgid )
2007-12-21 20:57:34 +03:00
{
struct winbindd_request request ;
struct winbindd_response response ;
2007-12-23 02:35:06 +03:00
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
2007-12-21 20:57:34 +03:00
if ( ! pgid )
return WBC_ERR_INVALID_PARAM ;
/* Initialise request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
/* Make request */
2007-12-23 02:35:06 +03:00
wbc_status = wbcRequestResponse ( WINBINDD_ALLOCATE_GID ,
2007-12-21 20:57:34 +03:00
& request , & response ) ;
2007-12-23 02:35:06 +03:00
BAIL_ON_WBC_ERROR ( wbc_status ) ;
2007-12-21 20:57:34 +03:00
/* Copy out result */
* pgid = response . data . gid ;
2007-12-23 02:35:06 +03:00
wbc_status = WBC_ERR_SUCCESS ;
done :
return wbc_status ;
2007-12-21 20:57:34 +03:00
}
2008-04-11 11:28:20 +04:00
/* we can't include smb.h here... */
# define _ID_TYPE_UID 1
# define _ID_TYPE_GID 2
2008-12-09 15:18:06 +03:00
/* Set an user id mapping */
2008-04-11 11:28:20 +04:00
wbcErr wbcSetUidMapping ( uid_t uid , const struct wbcDomainSid * sid )
{
struct winbindd_request request ;
struct winbindd_response response ;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
char * sid_string = NULL ;
if ( ! sid ) {
return WBC_ERR_INVALID_PARAM ;
}
/* Initialise request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
/* Make request */
request . data . dual_idmapset . id = uid ;
request . data . dual_idmapset . type = _ID_TYPE_UID ;
wbc_status = wbcSidToString ( sid , & sid_string ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
strncpy ( request . data . dual_idmapset . sid , sid_string ,
sizeof ( request . data . dual_idmapset . sid ) - 1 ) ;
wbcFreeMemory ( sid_string ) ;
wbc_status = wbcRequestResponse ( WINBINDD_SET_MAPPING ,
& request , & response ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
done :
return wbc_status ;
}
2008-12-09 15:18:06 +03:00
/* Set a group id mapping */
2008-04-11 11:28:20 +04:00
wbcErr wbcSetGidMapping ( gid_t gid , const struct wbcDomainSid * sid )
{
struct winbindd_request request ;
struct winbindd_response response ;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
char * sid_string = NULL ;
if ( ! sid ) {
return WBC_ERR_INVALID_PARAM ;
}
/* Initialise request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
/* Make request */
request . data . dual_idmapset . id = gid ;
request . data . dual_idmapset . type = _ID_TYPE_GID ;
wbc_status = wbcSidToString ( sid , & sid_string ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
strncpy ( request . data . dual_idmapset . sid , sid_string ,
sizeof ( request . data . dual_idmapset . sid ) - 1 ) ;
wbcFreeMemory ( sid_string ) ;
wbc_status = wbcRequestResponse ( WINBINDD_SET_MAPPING ,
& request , & response ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
done :
return wbc_status ;
}
2008-12-09 15:18:06 +03:00
/* Remove a user id mapping */
2008-10-28 09:37:55 +03:00
wbcErr wbcRemoveUidMapping ( uid_t uid , const struct wbcDomainSid * sid )
{
struct winbindd_request request ;
struct winbindd_response response ;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
char * sid_string = NULL ;
if ( ! sid ) {
return WBC_ERR_INVALID_PARAM ;
}
/* Initialise request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
/* Make request */
request . data . dual_idmapset . id = uid ;
request . data . dual_idmapset . type = _ID_TYPE_UID ;
wbc_status = wbcSidToString ( sid , & sid_string ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
strncpy ( request . data . dual_idmapset . sid , sid_string ,
sizeof ( request . data . dual_idmapset . sid ) - 1 ) ;
wbcFreeMemory ( sid_string ) ;
wbc_status = wbcRequestResponse ( WINBINDD_REMOVE_MAPPING ,
& request , & response ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
done :
return wbc_status ;
}
2008-12-09 15:18:06 +03:00
/* Remove a group id mapping */
2008-10-28 09:37:55 +03:00
wbcErr wbcRemoveGidMapping ( gid_t gid , const struct wbcDomainSid * sid )
{
struct winbindd_request request ;
struct winbindd_response response ;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
char * sid_string = NULL ;
if ( ! sid ) {
return WBC_ERR_INVALID_PARAM ;
}
/* Initialise request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
/* Make request */
request . data . dual_idmapset . id = gid ;
request . data . dual_idmapset . type = _ID_TYPE_GID ;
wbc_status = wbcSidToString ( sid , & sid_string ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
strncpy ( request . data . dual_idmapset . sid , sid_string ,
sizeof ( request . data . dual_idmapset . sid ) - 1 ) ;
wbcFreeMemory ( sid_string ) ;
wbc_status = wbcRequestResponse ( WINBINDD_REMOVE_MAPPING ,
& request , & response ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
done :
return wbc_status ;
}
2008-12-09 15:18:06 +03:00
/* Set the highwater mark for allocated uids. */
2008-04-11 11:28:20 +04:00
wbcErr wbcSetUidHwm ( uid_t uid_hwm )
{
struct winbindd_request request ;
struct winbindd_response response ;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
/* Initialise request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
/* Make request */
request . data . dual_idmapset . id = uid_hwm ;
request . data . dual_idmapset . type = _ID_TYPE_UID ;
wbc_status = wbcRequestResponse ( WINBINDD_SET_HWM ,
& request , & response ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
done :
return wbc_status ;
}
2008-12-09 15:18:06 +03:00
/* Set the highwater mark for allocated gids. */
2008-04-11 11:28:20 +04:00
wbcErr wbcSetGidHwm ( gid_t gid_hwm )
{
struct winbindd_request request ;
struct winbindd_response response ;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
/* Initialise request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
/* Make request */
request . data . dual_idmapset . id = gid_hwm ;
request . data . dual_idmapset . type = _ID_TYPE_GID ;
wbc_status = wbcRequestResponse ( WINBINDD_SET_HWM ,
& request , & response ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
done :
return wbc_status ;
}