2009-07-28 23:06:11 +04:00
/*
Unix SMB / CIFS implementation .
In - Child server implementation of the routines defined in wbint . idl
Copyright ( C ) Volker Lendecke 2009
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 "winbindd/winbindd.h"
# include "winbindd/winbindd_proto.h"
# include "librpc/gen_ndr/srv_wbint.h"
void _wbint_Ping ( pipes_struct * p , struct wbint_Ping * r )
{
* r - > out . out_data = r - > in . in_data ;
}
2009-08-04 01:44:46 +04:00
NTSTATUS _wbint_LookupSid ( pipes_struct * p , struct wbint_LookupSid * r )
{
struct winbindd_domain * domain = wb_child_domain ( ) ;
char * dom_name ;
char * name ;
enum lsa_SidType type ;
NTSTATUS status ;
if ( domain = = NULL ) {
return NT_STATUS_REQUEST_NOT_ACCEPTED ;
}
status = domain - > methods - > sid_to_name ( domain , p - > mem_ctx , r - > in . sid ,
& dom_name , & name , & type ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
* r - > out . domain = dom_name ;
* r - > out . name = name ;
* r - > out . type = type ;
return NT_STATUS_OK ;
}
2009-08-04 15:22:34 +04:00
NTSTATUS _wbint_LookupName ( pipes_struct * p , struct wbint_LookupName * r )
{
struct winbindd_domain * domain = wb_child_domain ( ) ;
if ( domain = = NULL ) {
return NT_STATUS_REQUEST_NOT_ACCEPTED ;
}
return domain - > methods - > name_to_sid (
domain , p - > mem_ctx , r - > in . domain , r - > in . name , r - > in . flags ,
r - > out . sid , r - > out . type ) ;
}
2009-08-04 21:28:59 +04:00
NTSTATUS _wbint_Sid2Uid ( pipes_struct * p , struct wbint_Sid2Uid * r )
{
uid_t uid ;
NTSTATUS status ;
status = idmap_sid_to_uid ( r - > in . dom_name ? r - > in . dom_name : " " ,
r - > in . sid , & uid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
* r - > out . uid = uid ;
return NT_STATUS_OK ;
}
2009-08-04 21:38:52 +04:00
NTSTATUS _wbint_Sid2Gid ( pipes_struct * p , struct wbint_Sid2Gid * r )
{
gid_t gid ;
NTSTATUS status ;
status = idmap_sid_to_gid ( r - > in . dom_name ? r - > in . dom_name : " " ,
r - > in . sid , & gid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
* r - > out . gid = gid ;
return NT_STATUS_OK ;
}
2009-08-04 21:52:39 +04:00
NTSTATUS _wbint_Uid2Sid ( pipes_struct * p , struct wbint_Uid2Sid * r )
{
2009-08-09 15:17:35 +04:00
return idmap_uid_to_sid ( r - > in . dom_name ? r - > in . dom_name : " " ,
r - > out . sid , r - > in . uid ) ;
2009-08-04 21:52:39 +04:00
}
2009-08-04 22:19:03 +04:00
NTSTATUS _wbint_Gid2Sid ( pipes_struct * p , struct wbint_Gid2Sid * r )
{
2009-08-09 15:17:35 +04:00
return idmap_gid_to_sid ( r - > in . dom_name ? r - > in . dom_name : " " ,
r - > out . sid , r - > in . gid ) ;
2009-08-04 22:19:03 +04:00
}
2009-08-04 23:23:13 +04:00
NTSTATUS _wbint_QueryUser ( pipes_struct * p , struct wbint_QueryUser * r )
{
struct winbindd_domain * domain = wb_child_domain ( ) ;
if ( domain = = NULL ) {
return NT_STATUS_REQUEST_NOT_ACCEPTED ;
}
2009-08-09 15:31:31 +04:00
return domain - > methods - > query_user ( domain , p - > mem_ctx , r - > in . sid ,
r - > out . info ) ;
2009-08-04 23:23:13 +04:00
}
2009-08-04 23:54:05 +04:00
NTSTATUS _wbint_LookupUserAliases ( pipes_struct * p ,
struct wbint_LookupUserAliases * r )
{
struct winbindd_domain * domain = wb_child_domain ( ) ;
if ( domain = = NULL ) {
return NT_STATUS_REQUEST_NOT_ACCEPTED ;
}
return domain - > methods - > lookup_useraliases (
domain , p - > mem_ctx , r - > in . sids - > num_sids , r - > in . sids - > sids ,
& r - > out . rids - > num_rids , & r - > out . rids - > rids ) ;
}
2009-08-05 00:07:01 +04:00
NTSTATUS _wbint_LookupUserGroups ( pipes_struct * p ,
struct wbint_LookupUserGroups * r )
{
struct winbindd_domain * domain = wb_child_domain ( ) ;
if ( domain = = NULL ) {
return NT_STATUS_REQUEST_NOT_ACCEPTED ;
}
return domain - > methods - > lookup_usergroups (
domain , p - > mem_ctx , r - > in . sid ,
& r - > out . sids - > num_sids , & r - > out . sids - > sids ) ;
}
2009-08-15 13:16:28 +04:00
NTSTATUS _wbint_QuerySequenceNumber ( pipes_struct * p ,
struct wbint_QuerySequenceNumber * r )
{
struct winbindd_domain * domain = wb_child_domain ( ) ;
if ( domain = = NULL ) {
return NT_STATUS_REQUEST_NOT_ACCEPTED ;
}
return domain - > methods - > sequence_number ( domain , r - > out . sequence ) ;
}
2009-08-16 12:58:43 +04:00
NTSTATUS _wbint_LookupGroupMembers ( pipes_struct * p ,
struct wbint_LookupGroupMembers * r )
{
struct winbindd_domain * domain = wb_child_domain ( ) ;
uint32_t i , num_names ;
struct dom_sid * sid_mem ;
char * * names ;
uint32_t * name_types ;
NTSTATUS status ;
if ( domain = = NULL ) {
return NT_STATUS_REQUEST_NOT_ACCEPTED ;
}
status = domain - > methods - > lookup_groupmem (
2009-08-28 16:25:11 +04:00
domain , p - > mem_ctx , r - > in . sid , r - > in . type ,
2009-08-16 12:58:43 +04:00
& num_names , & sid_mem , & names , & name_types ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2009-08-23 14:43:43 +04:00
r - > out . members - > num_principals = num_names ;
r - > out . members - > principals = talloc_array (
2009-08-23 14:38:35 +04:00
r - > out . members , struct wbint_Principal , num_names ) ;
2009-08-23 14:43:43 +04:00
if ( r - > out . members - > principals = = NULL ) {
2009-08-16 12:58:43 +04:00
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < num_names ; i + + ) {
2009-08-23 14:43:43 +04:00
struct wbint_Principal * m = & r - > out . members - > principals [ i ] ;
2009-08-16 12:58:43 +04:00
sid_copy ( & m - > sid , & sid_mem [ i ] ) ;
2009-08-23 14:43:43 +04:00
m - > name = talloc_move ( r - > out . members - > principals , & names [ i ] ) ;
2009-08-16 12:58:43 +04:00
m - > type = ( enum lsa_SidType ) name_types [ i ] ;
}
return NT_STATUS_OK ;
}
2009-08-18 00:40:19 +04:00
NTSTATUS _wbint_QueryUserList ( pipes_struct * p , struct wbint_QueryUserList * r )
{
struct winbindd_domain * domain = wb_child_domain ( ) ;
if ( domain = = NULL ) {
return NT_STATUS_REQUEST_NOT_ACCEPTED ;
}
return domain - > methods - > query_user_list (
domain , p - > mem_ctx , & r - > out . users - > num_userinfos ,
& r - > out . users - > userinfos ) ;
}
2009-08-26 00:13:34 +04:00
NTSTATUS _wbint_DsGetDcName ( pipes_struct * p , struct wbint_DsGetDcName * r )
{
struct winbindd_domain * domain = wb_child_domain ( ) ;
struct rpc_pipe_client * netlogon_pipe ;
struct netr_DsRGetDCNameInfo * dc_info ;
NTSTATUS status ;
WERROR werr ;
unsigned int orig_timeout ;
if ( domain = = NULL ) {
return dsgetdcname ( p - > mem_ctx , winbind_messaging_context ( ) ,
r - > in . domain_name , r - > in . domain_guid ,
r - > in . site_name ? r - > in . site_name : " " ,
r - > in . flags ,
r - > out . dc_info ) ;
}
status = cm_connect_netlogon ( domain , & netlogon_pipe ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 10 , ( " Can't contact the NETLOGON pipe \n " ) ) ;
return status ;
}
/* This call can take a long time - allow the server to time out.
35 seconds should do it . */
orig_timeout = rpccli_set_timeout ( netlogon_pipe , 35000 ) ;
if ( domain - > active_directory ) {
status = rpccli_netr_DsRGetDCName (
netlogon_pipe , p - > mem_ctx , domain - > dcname ,
r - > in . domain_name , NULL , r - > in . domain_guid ,
r - > in . flags , r - > out . dc_info , & werr ) ;
if ( NT_STATUS_IS_OK ( status ) & & W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
}
/*
* Fallback to less capable methods
*/
dc_info = talloc_zero ( r - > out . dc_info , struct netr_DsRGetDCNameInfo ) ;
if ( dc_info = = NULL ) {
status = NT_STATUS_NO_MEMORY ;
goto done ;
}
if ( r - > in . flags & DS_PDC_REQUIRED ) {
status = rpccli_netr_GetDcName (
netlogon_pipe , p - > mem_ctx , domain - > dcname ,
r - > in . domain_name , & dc_info - > dc_unc , & werr ) ;
} else {
status = rpccli_netr_GetAnyDCName (
netlogon_pipe , p - > mem_ctx , domain - > dcname ,
r - > in . domain_name , & dc_info - > dc_unc , & werr ) ;
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 10 , ( " rpccli_netr_Get[Any]DCName failed: %s \n " ,
nt_errstr ( status ) ) ) ;
goto done ;
}
if ( ! W_ERROR_IS_OK ( werr ) ) {
DEBUG ( 10 , ( " rpccli_netr_Get[Any]DCName failed: %s \n " ,
win_errstr ( werr ) ) ) ;
status = werror_to_ntstatus ( werr ) ;
goto done ;
}
* r - > out . dc_info = dc_info ;
status = NT_STATUS_OK ;
done :
/* And restore our original timeout. */
rpccli_set_timeout ( netlogon_pipe , orig_timeout ) ;
return status ;
}
2009-08-27 19:11:24 +04:00
NTSTATUS _wbint_LookupRids ( pipes_struct * p , struct wbint_LookupRids * r )
{
struct winbindd_domain * domain = wb_child_domain ( ) ;
char * domain_name ;
char * * names ;
enum lsa_SidType * types ;
struct wbint_Principal * result ;
NTSTATUS status ;
int i ;
if ( domain = = NULL ) {
return NT_STATUS_REQUEST_NOT_ACCEPTED ;
}
status = domain - > methods - > rids_to_names (
domain , talloc_tos ( ) , & domain - > sid , r - > in . rids - > rids ,
r - > in . rids - > num_rids , & domain_name , & names , & types ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
result = talloc_array ( p - > mem_ctx , struct wbint_Principal ,
r - > in . rids - > num_rids ) ;
if ( result = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < r - > in . rids - > num_rids ; i + + ) {
sid_compose ( & result [ i ] . sid , & domain - > sid , r - > in . rids - > rids [ i ] ) ;
result [ i ] . type = types [ i ] ;
result [ i ] . name = talloc_move ( result , & names [ i ] ) ;
}
TALLOC_FREE ( types ) ;
TALLOC_FREE ( names ) ;
r - > out . names - > num_principals = r - > in . rids - > num_rids ;
r - > out . names - > principals = result ;
return NT_STATUS_OK ;
}