2011-02-08 16:17:14 +03:00
/*
2002-01-30 09:08:46 +03:00
* Unix SMB / CIFS implementation .
2001-02-26 23:06:25 +03:00
* RPC Pipe client / server routines
2006-09-21 03:49:13 +04:00
*
* Copyright ( C ) Andrew Tridgell 1992 - 1997 ,
* Copyright ( C ) Gerald ( Jerry ) Carter 2006.
2008-03-29 01:39:57 +03:00
* Copyright ( C ) Guenther Deschner 2007 - 2008.
*
2001-02-26 23:06:25 +03:00
* 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
2007-07-09 23:25:36 +04:00
* the Free Software Foundation ; either version 3 of the License , or
2001-02-26 23:06:25 +03:00
* ( at your option ) any later version .
2011-02-08 16:17:14 +03:00
*
2001-02-26 23:06:25 +03:00
* 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 .
2011-02-08 16:17:14 +03:00
*
2001-02-26 23:06:25 +03:00
* You should have received a copy of the GNU General Public License
2007-07-10 09:23:25 +04:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2001-02-26 23:06:25 +03:00
*/
/* This is the implementation of the wks interface. */
# include "includes.h"
2011-05-02 15:21:53 +04:00
# include "ntdomain.h"
2010-07-02 02:14:04 +04:00
# include "librpc/gen_ndr/libnet_join.h"
# include "libnet/libnet_join.h"
2009-03-16 13:27:58 +03:00
# include "../libcli/auth/libcli_auth.h"
2009-11-26 20:21:28 +03:00
# include "../librpc/gen_ndr/srv_wkssvc.h"
2010-10-12 08:27:50 +04:00
# include "../libcli/security/security.h"
2011-02-25 01:14:15 +03:00
# include "session.h"
2011-03-23 01:49:33 +03:00
# include "smbd/smbd.h"
2011-03-24 14:08:15 +03:00
# include "auth.h"
2011-09-21 19:28:58 +04:00
# include "krb5_env.h"
2001-02-26 23:06:25 +03:00
2002-07-15 14:35:28 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_RPC_SRV
2009-11-23 02:00:00 +03:00
struct dom_usr {
char * name ;
char * domain ;
time_t login_time ;
} ;
2009-08-03 18:52:01 +04:00
# ifdef HAVE_GETUTXENT
# include <utmpx.h>
2009-11-23 02:00:00 +03:00
struct usrinfo {
char * name ;
struct timeval login_time ;
} ;
2010-02-14 02:02:54 +03:00
static int usr_info_cmp ( const struct usrinfo * usr1 , const struct usrinfo * usr2 )
2009-11-23 02:00:00 +03:00
{
/* Called from qsort to compare two users in a usrinfo_t array for
* sorting by login time . Return > 0 if usr1 login time was later than
* usr2 login time , < 0 if it was earlier */
2009-12-06 14:49:09 +03:00
return timeval_compare ( & usr1 - > login_time , & usr2 - > login_time ) ;
2009-11-23 02:00:00 +03:00
}
/*******************************************************************
Get a list of the names of all users logged into this machine
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-08-03 18:52:01 +04:00
static char * * get_logged_on_userlist ( TALLOC_CTX * mem_ctx )
{
2009-11-23 02:00:00 +03:00
char * * users ;
int i , num_users = 0 ;
struct usrinfo * usr_infos = NULL ;
2009-08-03 18:52:01 +04:00
struct utmpx * u ;
while ( ( u = getutxent ( ) ) ! = NULL ) {
2009-11-23 02:00:00 +03:00
struct usrinfo * tmp ;
2009-08-03 19:27:11 +04:00
if ( u - > ut_type ! = USER_PROCESS ) {
continue ;
}
2009-11-23 02:00:00 +03:00
for ( i = 0 ; i < num_users ; i + + ) {
/* getutxent can return multiple user entries for the
* same user , so ignore any dups */
if ( strcmp ( u - > ut_user , usr_infos [ i ] . name ) = = 0 ) {
break ;
}
}
if ( i < num_users ) {
continue ;
}
tmp = talloc_realloc ( mem_ctx , usr_infos , struct usrinfo ,
num_users + 1 ) ;
2009-08-03 18:52:01 +04:00
if ( tmp = = NULL ) {
2009-11-23 02:00:00 +03:00
TALLOC_FREE ( tmp ) ;
endutxent ( ) ;
2009-08-03 18:52:01 +04:00
return NULL ;
}
2009-11-23 02:00:00 +03:00
usr_infos = tmp ;
usr_infos [ num_users ] . name = talloc_strdup ( usr_infos ,
u - > ut_user ) ;
if ( usr_infos [ num_users ] . name = = NULL ) {
TALLOC_FREE ( usr_infos ) ;
endutxent ( ) ;
2009-08-03 18:52:01 +04:00
return NULL ;
}
2009-11-23 02:00:00 +03:00
usr_infos [ num_users ] . login_time . tv_sec = u - > ut_tv . tv_sec ;
usr_infos [ num_users ] . login_time . tv_usec = u - > ut_tv . tv_usec ;
2009-08-03 19:27:11 +04:00
num_users + = 1 ;
2009-08-03 18:52:01 +04:00
}
2009-11-23 02:00:00 +03:00
/* Sort the user list by time, oldest first */
2010-02-14 02:02:54 +03:00
TYPESAFE_QSORT ( usr_infos , num_users , usr_info_cmp ) ;
2009-11-23 02:00:00 +03:00
users = ( char * * ) talloc_array ( mem_ctx , char * , num_users ) ;
if ( users ) {
for ( i = 0 ; i < num_users ; i + + ) {
users [ i ] = talloc_move ( users , & usr_infos [ i ] . name ) ;
}
}
TALLOC_FREE ( usr_infos ) ;
endutxent ( ) ;
errno = 0 ;
2009-08-03 18:52:01 +04:00
return users ;
}
# else
static char * * get_logged_on_userlist ( TALLOC_CTX * mem_ctx )
{
return NULL ;
}
# endif
2010-02-14 02:02:54 +03:00
static int dom_user_cmp ( const struct dom_usr * usr1 , const struct dom_usr * usr2 )
2009-11-23 02:00:00 +03:00
{
/* Called from qsort to compare two domain users in a dom_usr_t array
* for sorting by login time . Return > 0 if usr1 login time was later
* than usr2 login time , < 0 if it was earlier */
return ( usr1 - > login_time - usr2 - > login_time ) ;
}
/*******************************************************************
Get a list of the names of all users of this machine who are
logged into the domain .
This should return a list of the users on this machine who are
logged into the domain ( i . e . have been authenticated by the domain ' s
password server ) but that doesn ' t fit well with the normal Samba
scenario where accesses out to the domain are made through smbclient
with each such session individually authenticated . So about the best
we can do currently is to list sessions of local users connected to
this server , which means that to get themself included in the list a
local user must create a session to the local samba server by running :
smbclient \ \ \ \ localhost \ \ share
FIXME : find a better way to get local users logged into the domain
in this list .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static struct dom_usr * get_domain_userlist ( TALLOC_CTX * mem_ctx )
{
struct sessionid * session_list = NULL ;
char * machine_name , * p , * nm ;
const char * sep ;
struct dom_usr * users , * tmp ;
int i , num_users , num_sessions ;
sep = lp_winbind_separator ( ) ;
if ( ! sep ) {
sep = " \\ " ;
}
num_sessions = list_sessions ( mem_ctx , & session_list ) ;
if ( num_sessions = = 0 ) {
errno = 0 ;
return NULL ;
}
users = talloc_array ( mem_ctx , struct dom_usr , num_sessions ) ;
if ( users = = NULL ) {
TALLOC_FREE ( session_list ) ;
return NULL ;
}
for ( i = num_users = 0 ; i < num_sessions ; i + + ) {
2012-12-19 14:20:50 +04:00
if ( session_list [ i ] . username [ 0 ] = = ' \0 ' | |
session_list [ i ] . remote_machine [ 0 ] = = ' \0 ' ) {
2009-11-23 02:00:00 +03:00
continue ;
}
p = strpbrk ( session_list [ i ] . remote_machine , " ./ " ) ;
if ( p ) {
* p = ' \0 ' ;
}
machine_name = talloc_asprintf_strupper_m (
users , " %s " , session_list [ i ] . remote_machine ) ;
if ( machine_name = = NULL ) {
DEBUG ( 10 , ( " talloc_asprintf failed \n " ) ) ;
continue ;
}
2011-06-09 09:31:03 +04:00
if ( strcmp ( machine_name , lp_netbios_name ( ) ) = = 0 ) {
2009-11-23 02:00:00 +03:00
p = session_list [ i ] . username ;
nm = strstr ( p , sep ) ;
if ( nm ) {
/*
* " domain+name " format so split domain and
* name components
*/
* nm = ' \0 ' ;
nm + = strlen ( sep ) ;
users [ num_users ] . domain =
talloc_asprintf_strupper_m ( users ,
" %s " , p ) ;
users [ num_users ] . name = talloc_strdup ( users ,
nm ) ;
} else {
/*
* Simple user name so get domain from smb . conf
*/
users [ num_users ] . domain =
talloc_strdup ( users , lp_workgroup ( ) ) ;
users [ num_users ] . name = talloc_strdup ( users ,
p ) ;
}
users [ num_users ] . login_time =
session_list [ i ] . connect_start ;
num_users + + ;
}
TALLOC_FREE ( machine_name ) ;
}
TALLOC_FREE ( session_list ) ;
tmp = talloc_realloc ( mem_ctx , users , struct dom_usr , num_users ) ;
if ( tmp = = NULL ) {
return NULL ;
}
users = tmp ;
/* Sort the user list by time, oldest first */
2010-02-14 02:02:54 +03:00
TYPESAFE_QSORT ( users , num_users , dom_user_cmp ) ;
2009-11-23 02:00:00 +03:00
errno = 0 ;
return users ;
}
2001-02-26 23:06:25 +03:00
/*******************************************************************
2009-11-23 02:00:00 +03:00
RPC Workstation Service request NetWkstaGetInfo with level 100.
Returns to the requester :
- The machine name .
- The smb version number
- The domain name .
Returns a filled in wkssvc_NetWkstaInfo100 struct .
2001-02-26 23:06:25 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-08-03 18:52:01 +04:00
static struct wkssvc_NetWkstaInfo100 * create_wks_info_100 ( TALLOC_CTX * mem_ctx )
2001-02-26 23:06:25 +03:00
{
2009-08-03 18:52:01 +04:00
struct wkssvc_NetWkstaInfo100 * info100 ;
info100 = talloc ( mem_ctx , struct wkssvc_NetWkstaInfo100 ) ;
if ( info100 = = NULL ) {
return NULL ;
}
2007-12-21 00:17:16 +03:00
info100 - > platform_id = PLATFORM_ID_NT ; /* unknown */
2011-06-21 09:14:29 +04:00
info100 - > version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION ;
info100 - > version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION ;
2001-02-26 23:06:25 +03:00
2007-11-24 19:27:54 +03:00
info100 - > server_name = talloc_asprintf_strupper_m (
2011-06-09 09:31:03 +04:00
info100 , " %s " , lp_netbios_name ( ) ) ;
2007-11-24 19:27:54 +03:00
info100 - > domain_name = talloc_asprintf_strupper_m (
info100 , " %s " , lp_workgroup ( ) ) ;
2001-02-26 23:06:25 +03:00
2009-08-03 18:52:01 +04:00
return info100 ;
}
2009-11-23 02:00:00 +03:00
/*******************************************************************
RPC Workstation Service request NetWkstaGetInfo with level 101.
Returns to the requester :
- As per NetWkstaGetInfo with level 100 , plus :
- The LANMAN directory path ( not currently supported ) .
Returns a filled in wkssvc_NetWkstaInfo101 struct .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-08-03 18:52:01 +04:00
static struct wkssvc_NetWkstaInfo101 * create_wks_info_101 ( TALLOC_CTX * mem_ctx )
{
struct wkssvc_NetWkstaInfo101 * info101 ;
info101 = talloc ( mem_ctx , struct wkssvc_NetWkstaInfo101 ) ;
if ( info101 = = NULL ) {
return NULL ;
}
info101 - > platform_id = PLATFORM_ID_NT ; /* unknown */
2011-06-21 09:14:29 +04:00
info101 - > version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION ;
info101 - > version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION ;
2009-08-03 18:52:01 +04:00
info101 - > server_name = talloc_asprintf_strupper_m (
2011-06-09 09:31:03 +04:00
info101 , " %s " , lp_netbios_name ( ) ) ;
2009-08-03 18:52:01 +04:00
info101 - > domain_name = talloc_asprintf_strupper_m (
info101 , " %s " , lp_workgroup ( ) ) ;
2009-11-23 02:00:00 +03:00
info101 - > lan_root = " " ;
2009-08-03 18:52:01 +04:00
return info101 ;
}
2009-11-23 02:00:00 +03:00
/*******************************************************************
RPC Workstation Service request NetWkstaGetInfo with level 102.
Returns to the requester :
- As per NetWkstaGetInfo with level 101 , plus :
- The number of logged in users .
Returns a filled in wkssvc_NetWkstaInfo102 struct .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-08-03 18:52:01 +04:00
static struct wkssvc_NetWkstaInfo102 * create_wks_info_102 ( TALLOC_CTX * mem_ctx )
{
struct wkssvc_NetWkstaInfo102 * info102 ;
char * * users ;
info102 = talloc ( mem_ctx , struct wkssvc_NetWkstaInfo102 ) ;
if ( info102 = = NULL ) {
return NULL ;
}
info102 - > platform_id = PLATFORM_ID_NT ; /* unknown */
2011-06-21 09:14:29 +04:00
info102 - > version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION ;
info102 - > version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION ;
2009-08-03 18:52:01 +04:00
info102 - > server_name = talloc_asprintf_strupper_m (
2011-06-09 09:31:03 +04:00
info102 , " %s " , lp_netbios_name ( ) ) ;
2009-08-03 18:52:01 +04:00
info102 - > domain_name = talloc_asprintf_strupper_m (
info102 , " %s " , lp_workgroup ( ) ) ;
2009-11-23 02:00:00 +03:00
info102 - > lan_root = " " ;
2009-08-03 18:52:01 +04:00
users = get_logged_on_userlist ( talloc_tos ( ) ) ;
info102 - > logged_on_users = talloc_array_length ( users ) ;
2009-11-23 02:00:00 +03:00
2009-08-03 18:52:01 +04:00
TALLOC_FREE ( users ) ;
return info102 ;
2001-02-26 23:06:25 +03:00
}
2006-09-20 23:26:21 +04:00
/********************************************************************
2009-11-23 02:00:00 +03:00
Handling for RPC Workstation Service request NetWkstaGetInfo
2006-09-20 23:26:21 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetWkstaGetInfo ( struct pipes_struct * p ,
struct wkssvc_NetWkstaGetInfo * r )
2006-09-20 23:26:21 +04:00
{
2009-08-03 18:52:01 +04:00
switch ( r - > in . level ) {
case 100 :
2009-11-23 02:00:00 +03:00
/* Level 100 can be allowed from anyone including anonymous
* so no access checks are needed for this case */
2009-08-03 18:52:01 +04:00
r - > out . info - > info100 = create_wks_info_100 ( p - > mem_ctx ) ;
if ( r - > out . info - > info100 = = NULL ) {
2015-12-03 17:24:15 +03:00
return WERR_NOT_ENOUGH_MEMORY ;
2009-08-03 18:52:01 +04:00
}
break ;
case 101 :
2009-11-23 02:00:00 +03:00
/* Level 101 can be allowed from any logged in user */
if ( ! nt_token_check_sid ( & global_sid_Authenticated_Users ,
2011-02-21 12:25:52 +03:00
p - > session_info - > security_token ) ) {
2009-11-23 02:00:00 +03:00
DEBUG ( 1 , ( " User not allowed for NetWkstaGetInfo level "
" 101 \n " ) ) ;
DEBUGADD ( 3 , ( " - does not have sid for Authenticated "
" Users %s: \n " ,
sid_string_dbg (
& global_sid_Authenticated_Users ) ) ) ;
2010-09-17 09:31:28 +04:00
security_token_debug ( DBGC_CLASS , 3 ,
2011-02-21 12:25:52 +03:00
p - > session_info - > security_token ) ;
2009-11-23 02:00:00 +03:00
return WERR_ACCESS_DENIED ;
}
2009-08-03 18:52:01 +04:00
r - > out . info - > info101 = create_wks_info_101 ( p - > mem_ctx ) ;
if ( r - > out . info - > info101 = = NULL ) {
2015-12-03 17:24:15 +03:00
return WERR_NOT_ENOUGH_MEMORY ;
2009-08-03 18:52:01 +04:00
}
break ;
case 102 :
2009-11-23 02:00:00 +03:00
/* Level 102 Should only be allowed from a domain administrator */
if ( ! nt_token_check_sid ( & global_sid_Builtin_Administrators ,
2011-02-21 12:25:52 +03:00
p - > session_info - > security_token ) ) {
2009-11-23 02:00:00 +03:00
DEBUG ( 1 , ( " User not allowed for NetWkstaGetInfo level "
" 102 \n " ) ) ;
DEBUGADD ( 3 , ( " - does not have sid for Administrators "
" group %s, sids are: \n " ,
sid_string_dbg ( & global_sid_Builtin_Administrators ) ) ) ;
2010-09-17 09:31:28 +04:00
security_token_debug ( DBGC_CLASS , 3 ,
2011-02-21 12:25:52 +03:00
p - > session_info - > security_token ) ;
2009-11-23 02:00:00 +03:00
return WERR_ACCESS_DENIED ;
}
2009-08-03 18:52:01 +04:00
r - > out . info - > info102 = create_wks_info_102 ( p - > mem_ctx ) ;
if ( r - > out . info - > info102 = = NULL ) {
2015-12-03 17:24:15 +03:00
return WERR_NOT_ENOUGH_MEMORY ;
2009-08-03 18:52:01 +04:00
}
break ;
default :
2015-12-03 17:24:42 +03:00
return WERR_INVALID_LEVEL ;
2006-09-20 23:26:21 +04:00
}
2006-09-21 00:45:23 +04:00
return WERR_OK ;
2006-09-20 23:26:21 +04:00
}
/********************************************************************
2006-09-20 21:56:50 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetWkstaSetInfo ( struct pipes_struct * p ,
struct wkssvc_NetWkstaSetInfo * r )
2006-09-20 21:56:50 +04:00
{
2006-09-20 23:26:21 +04:00
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
2006-09-20 21:56:50 +04:00
2009-11-23 02:00:00 +03:00
/********************************************************************
RPC Workstation Service request NetWkstaEnumUsers with level 0 :
Returns to the requester :
- the user names of the logged in users .
Returns a filled in wkssvc_NetWkstaEnumUsersCtr0 struct .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-08-03 19:27:11 +04:00
static struct wkssvc_NetWkstaEnumUsersCtr0 * create_enum_users0 (
TALLOC_CTX * mem_ctx )
{
struct wkssvc_NetWkstaEnumUsersCtr0 * ctr0 ;
char * * users ;
int i , num_users ;
ctr0 = talloc ( mem_ctx , struct wkssvc_NetWkstaEnumUsersCtr0 ) ;
if ( ctr0 = = NULL ) {
return NULL ;
}
users = get_logged_on_userlist ( talloc_tos ( ) ) ;
2009-11-23 02:00:00 +03:00
if ( users = = NULL & & errno ! = 0 ) {
DEBUG ( 1 , ( " get_logged_on_userlist error %d: %s \n " ,
errno , strerror ( errno ) ) ) ;
2009-08-03 19:27:11 +04:00
TALLOC_FREE ( ctr0 ) ;
return NULL ;
}
2009-12-06 14:50:25 +03:00
num_users = talloc_array_length ( users ) ;
2009-08-03 19:27:11 +04:00
ctr0 - > entries_read = num_users ;
ctr0 - > user0 = talloc_array ( ctr0 , struct wkssvc_NetrWkstaUserInfo0 ,
num_users ) ;
if ( ctr0 - > user0 = = NULL ) {
TALLOC_FREE ( ctr0 ) ;
TALLOC_FREE ( users ) ;
return NULL ;
}
for ( i = 0 ; i < num_users ; i + + ) {
ctr0 - > user0 [ i ] . user_name = talloc_move ( ctr0 - > user0 , & users [ i ] ) ;
}
TALLOC_FREE ( users ) ;
return ctr0 ;
}
2006-09-20 23:26:21 +04:00
/********************************************************************
2009-11-23 02:00:00 +03:00
RPC Workstation Service request NetWkstaEnumUsers with level 1.
Returns to the requester :
- the user names of the logged in users ,
- the domain or machine each is logged into ,
- the password server that was used to authenticate each ,
- other domains each user is logged into ( not currently supported ) .
Returns a filled in wkssvc_NetWkstaEnumUsersCtr1 struct .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static struct wkssvc_NetWkstaEnumUsersCtr1 * create_enum_users1 (
TALLOC_CTX * mem_ctx )
{
struct wkssvc_NetWkstaEnumUsersCtr1 * ctr1 ;
char * * users ;
struct dom_usr * dom_users ;
2009-12-06 14:50:51 +03:00
const char * pwd_server ;
char * pwd_tmp ;
2009-11-23 02:00:00 +03:00
int i , j , num_users , num_dom_users ;
ctr1 = talloc ( mem_ctx , struct wkssvc_NetWkstaEnumUsersCtr1 ) ;
if ( ctr1 = = NULL ) {
return NULL ;
}
users = get_logged_on_userlist ( talloc_tos ( ) ) ;
if ( users = = NULL & & errno ! = 0 ) {
DEBUG ( 1 , ( " get_logged_on_userlist error %d: %s \n " ,
errno , strerror ( errno ) ) ) ;
TALLOC_FREE ( ctr1 ) ;
return NULL ;
}
2009-12-06 14:50:25 +03:00
num_users = talloc_array_length ( users ) ;
2009-11-23 02:00:00 +03:00
dom_users = get_domain_userlist ( talloc_tos ( ) ) ;
if ( dom_users = = NULL & & errno ! = 0 ) {
TALLOC_FREE ( ctr1 ) ;
TALLOC_FREE ( users ) ;
return NULL ;
}
2009-12-06 14:50:25 +03:00
num_dom_users = talloc_array_length ( dom_users ) ;
2009-11-23 02:00:00 +03:00
ctr1 - > user1 = talloc_array ( ctr1 , struct wkssvc_NetrWkstaUserInfo1 ,
num_users + num_dom_users ) ;
if ( ctr1 - > user1 = = NULL ) {
TALLOC_FREE ( ctr1 ) ;
TALLOC_FREE ( users ) ;
TALLOC_FREE ( dom_users ) ;
return NULL ;
}
2009-12-06 14:50:51 +03:00
pwd_server = " " ;
2014-02-03 06:52:14 +04:00
if ( ( pwd_tmp = talloc_strdup ( ctr1 - > user1 , lp_password_server ( ) ) ) ) {
2009-11-23 02:00:00 +03:00
/* The configured password server is a full DNS name but
* for the logon server we need to return just the first
* component ( machine name ) of it in upper - case */
2009-12-06 14:50:51 +03:00
char * p = strchr ( pwd_tmp , ' . ' ) ;
2009-11-23 02:00:00 +03:00
if ( p ) {
* p = ' \0 ' ;
} else {
2009-12-06 14:50:51 +03:00
p = pwd_tmp + strlen ( pwd_tmp ) ;
2009-11-23 02:00:00 +03:00
}
2009-12-06 14:50:51 +03:00
while ( - - p > = pwd_tmp ) {
2009-11-23 02:00:00 +03:00
* p = toupper ( * p ) ;
}
2009-12-06 14:50:51 +03:00
pwd_server = pwd_tmp ;
2009-11-23 02:00:00 +03:00
}
/* Put in local users first */
for ( i = 0 ; i < num_users ; i + + ) {
ctr1 - > user1 [ i ] . user_name = talloc_move ( ctr1 - > user1 , & users [ i ] ) ;
/* For a local user the domain name and logon server are
* both returned as the local machine ' s NetBIOS name */
ctr1 - > user1 [ i ] . logon_domain = ctr1 - > user1 [ i ] . logon_server =
2011-06-09 09:31:03 +04:00
talloc_asprintf_strupper_m ( ctr1 - > user1 , " %s " , lp_netbios_name ( ) ) ;
2009-11-23 02:00:00 +03:00
ctr1 - > user1 [ i ] . other_domains = NULL ; /* Maybe in future? */
}
/* Now domain users */
for ( j = 0 ; j < num_dom_users ; j + + ) {
ctr1 - > user1 [ i ] . user_name =
talloc_strdup ( ctr1 - > user1 , dom_users [ j ] . name ) ;
ctr1 - > user1 [ i ] . logon_domain =
talloc_strdup ( ctr1 - > user1 , dom_users [ j ] . domain ) ;
ctr1 - > user1 [ i ] . logon_server = pwd_server ;
ctr1 - > user1 [ i + + ] . other_domains = NULL ; /* Maybe in future? */
}
ctr1 - > entries_read = i ;
TALLOC_FREE ( users ) ;
TALLOC_FREE ( dom_users ) ;
return ctr1 ;
}
/********************************************************************
Handling for RPC Workstation Service request NetWkstaEnumUsers
( a . k . a Windows NetWkstaUserEnum )
2006-09-20 23:26:21 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-20 21:56:50 +04:00
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetWkstaEnumUsers ( struct pipes_struct * p ,
struct wkssvc_NetWkstaEnumUsers * r )
2006-09-20 23:26:21 +04:00
{
2009-11-23 02:00:00 +03:00
/* This with any level should only be allowed from a domain administrator */
if ( ! nt_token_check_sid ( & global_sid_Builtin_Administrators ,
2011-02-21 12:25:52 +03:00
p - > session_info - > security_token ) ) {
2009-11-23 02:00:00 +03:00
DEBUG ( 1 , ( " User not allowed for NetWkstaEnumUsers \n " ) ) ;
DEBUGADD ( 3 , ( " - does not have sid for Administrators group "
" %s \n " , sid_string_dbg (
& global_sid_Builtin_Administrators ) ) ) ;
2011-02-21 12:25:52 +03:00
security_token_debug ( DBGC_CLASS , 3 , p - > session_info - > security_token ) ;
2009-11-23 02:00:00 +03:00
return WERR_ACCESS_DENIED ;
2009-08-03 19:27:11 +04:00
}
2009-11-23 02:00:00 +03:00
switch ( r - > in . info - > level ) {
case 0 :
r - > out . info - > ctr . user0 = create_enum_users0 ( p - > mem_ctx ) ;
if ( r - > out . info - > ctr . user0 = = NULL ) {
2015-12-03 17:24:15 +03:00
return WERR_NOT_ENOUGH_MEMORY ;
2009-11-23 02:00:00 +03:00
}
r - > out . info - > level = r - > in . info - > level ;
* r - > out . entries_read = r - > out . info - > ctr . user0 - > entries_read ;
2013-03-18 12:36:17 +04:00
if ( r - > out . resume_handle ! = NULL ) {
* r - > out . resume_handle = 0 ;
}
2009-11-23 02:00:00 +03:00
break ;
case 1 :
r - > out . info - > ctr . user1 = create_enum_users1 ( p - > mem_ctx ) ;
if ( r - > out . info - > ctr . user1 = = NULL ) {
2015-12-03 17:24:15 +03:00
return WERR_NOT_ENOUGH_MEMORY ;
2009-11-23 02:00:00 +03:00
}
r - > out . info - > level = r - > in . info - > level ;
* r - > out . entries_read = r - > out . info - > ctr . user1 - > entries_read ;
2013-03-18 12:36:17 +04:00
if ( r - > out . resume_handle ! = NULL ) {
* r - > out . resume_handle = 0 ;
}
2009-11-23 02:00:00 +03:00
break ;
default :
2015-12-03 17:24:42 +03:00
return WERR_INVALID_LEVEL ;
2009-08-03 19:27:11 +04:00
}
return WERR_OK ;
2006-09-20 23:26:21 +04:00
}
2001-02-26 23:06:25 +03:00
2006-09-20 23:26:21 +04:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrWkstaUserGetInfo ( struct pipes_struct * p ,
struct wkssvc_NetrWkstaUserGetInfo * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrWkstaUserSetInfo ( struct pipes_struct * p ,
struct wkssvc_NetrWkstaUserSetInfo * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetWkstaTransportEnum ( struct pipes_struct * p ,
struct wkssvc_NetWkstaTransportEnum * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrWkstaTransportAdd ( struct pipes_struct * p ,
struct wkssvc_NetrWkstaTransportAdd * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrWkstaTransportDel ( struct pipes_struct * p ,
struct wkssvc_NetrWkstaTransportDel * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrUseAdd ( struct pipes_struct * p ,
struct wkssvc_NetrUseAdd * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrUseGetInfo ( struct pipes_struct * p ,
struct wkssvc_NetrUseGetInfo * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrUseDel ( struct pipes_struct * p ,
struct wkssvc_NetrUseDel * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrUseEnum ( struct pipes_struct * p ,
struct wkssvc_NetrUseEnum * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrMessageBufferSend ( struct pipes_struct * p ,
struct wkssvc_NetrMessageBufferSend * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrWorkstationStatisticsGet ( struct pipes_struct * p ,
struct wkssvc_NetrWorkstationStatisticsGet * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrLogonDomainNameAdd ( struct pipes_struct * p ,
struct wkssvc_NetrLogonDomainNameAdd * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrLogonDomainNameDel ( struct pipes_struct * p ,
struct wkssvc_NetrLogonDomainNameDel * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrJoinDomain ( struct pipes_struct * p ,
struct wkssvc_NetrJoinDomain * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrUnjoinDomain ( struct pipes_struct * p ,
struct wkssvc_NetrUnjoinDomain * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrRenameMachineInDomain ( struct pipes_struct * p ,
struct wkssvc_NetrRenameMachineInDomain * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrValidateName ( struct pipes_struct * p ,
struct wkssvc_NetrValidateName * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrGetJoinInformation ( struct pipes_struct * p ,
struct wkssvc_NetrGetJoinInformation * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrGetJoinableOus ( struct pipes_struct * p ,
struct wkssvc_NetrGetJoinableOus * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
2008-02-28 22:01:32 +03:00
_wkssvc_NetrJoinDomain2
2006-09-20 23:26:21 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrJoinDomain2 ( struct pipes_struct * p ,
2008-02-28 22:01:32 +03:00
struct wkssvc_NetrJoinDomain2 * r )
2006-09-20 23:26:21 +04:00
{
2007-12-12 18:12:14 +03:00
struct libnet_JoinCtx * j = NULL ;
2008-01-16 13:02:52 +03:00
char * cleartext_pwd = NULL ;
2007-12-12 18:12:14 +03:00
char * admin_domain = NULL ;
char * admin_account = NULL ;
WERROR werr ;
2011-02-21 12:25:52 +03:00
struct security_token * token = p - > session_info - > security_token ;
2012-08-04 12:05:51 +04:00
NTSTATUS status ;
DATA_BLOB session_key ;
2016-09-20 20:51:15 +03:00
bool ok ;
2007-12-12 18:12:14 +03:00
if ( ! r - > in . domain_name ) {
2015-12-03 17:24:25 +03:00
return WERR_INVALID_PARAMETER ;
2007-12-12 18:12:14 +03:00
}
2008-03-29 01:39:57 +03:00
if ( ! r - > in . admin_account | | ! r - > in . encrypted_password ) {
2015-12-03 17:24:25 +03:00
return WERR_INVALID_PARAMETER ;
2008-03-29 01:39:57 +03:00
}
2010-10-23 02:58:40 +04:00
if ( ! security_token_has_privilege ( token , SEC_PRIV_MACHINE_ACCOUNT ) & &
2010-05-18 00:04:24 +04:00
! nt_token_check_domain_rid ( token , DOMAIN_RID_ADMINS ) & &
2009-08-06 22:59:32 +04:00
! nt_token_check_sid ( & global_sid_Builtin_Administrators , token ) ) {
2008-02-28 22:01:32 +03:00
DEBUG ( 5 , ( " _wkssvc_NetrJoinDomain2: account doesn't have "
" sufficient privileges \n " ) ) ;
2007-12-12 18:12:14 +03:00
return WERR_ACCESS_DENIED ;
}
2008-03-29 01:39:57 +03:00
if ( ( r - > in . join_flags & WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED ) | |
( r - > in . join_flags & WKSSVC_JOIN_FLAGS_JOIN_UNSECURE ) ) {
return WERR_NOT_SUPPORTED ;
}
2012-08-04 12:05:51 +04:00
status = session_extract_session_key ( p - > session_info ,
& session_key ,
KEY_USE_16BYTES ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 5 , ( " _wkssvc_NetrJoinDomain2: no session key %s \n " ,
nt_errstr ( status ) ) ) ;
return WERR_NO_USER_SESSION_KEY ;
}
2008-06-24 16:33:31 +04:00
werr = decode_wkssvc_join_password_buffer (
p - > mem_ctx , r - > in . encrypted_password ,
2012-08-04 12:05:51 +04:00
& session_key , & cleartext_pwd ) ;
2007-12-12 18:12:14 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
return werr ;
}
2016-09-20 20:51:15 +03:00
ok = split_domain_user ( p - > mem_ctx ,
r - > in . admin_account ,
& admin_domain ,
& admin_account ) ;
if ( ! ok ) {
2015-12-03 17:24:15 +03:00
return WERR_NOT_ENOUGH_MEMORY ;
2016-09-20 20:51:15 +03:00
}
2007-12-12 18:12:14 +03:00
2008-01-16 13:02:52 +03:00
werr = libnet_init_JoinCtx ( p - > mem_ctx , & j ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
return werr ;
}
2007-12-12 18:12:14 +03:00
j - > in . domain_name = r - > in . domain_name ;
j - > in . account_ou = r - > in . account_ou ;
j - > in . join_flags = r - > in . join_flags ;
2008-01-16 13:02:52 +03:00
j - > in . admin_account = admin_account ;
j - > in . admin_password = cleartext_pwd ;
2008-02-28 22:01:32 +03:00
j - > in . debug = true ;
2008-04-14 16:46:30 +04:00
j - > in . modify_config = lp_config_backend_is_registry ( ) ;
2010-08-07 13:58:48 +04:00
j - > in . msg_ctx = p - > msg_ctx ;
2007-12-12 18:12:14 +03:00
become_root ( ) ;
2011-09-21 19:28:58 +04:00
setenv ( KRB5_ENV_CCNAME , " MEMORY:_wkssvc_NetrJoinDomain2 " , 1 ) ;
2007-12-12 18:12:14 +03:00
werr = libnet_Join ( p - > mem_ctx , j ) ;
2011-09-21 19:28:58 +04:00
unsetenv ( KRB5_ENV_CCNAME ) ;
2007-12-12 18:12:14 +03:00
unbecome_root ( ) ;
2008-02-28 22:01:32 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
2008-03-29 01:39:57 +03:00
DEBUG ( 5 , ( " _wkssvc_NetrJoinDomain2: libnet_Join failed with: %s \n " ,
2008-02-28 22:01:32 +03:00
j - > out . error_string ? j - > out . error_string :
2008-11-01 19:19:26 +03:00
win_errstr ( werr ) ) ) ;
2008-02-28 22:01:32 +03:00
}
TALLOC_FREE ( j ) ;
2007-12-12 18:12:14 +03:00
return werr ;
2006-09-20 23:26:21 +04:00
}
/********************************************************************
2008-02-28 23:55:01 +03:00
_wkssvc_NetrUnjoinDomain2
2006-09-20 23:26:21 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrUnjoinDomain2 ( struct pipes_struct * p ,
2008-02-28 23:55:01 +03:00
struct wkssvc_NetrUnjoinDomain2 * r )
2006-09-20 23:26:21 +04:00
{
2008-02-28 23:55:01 +03:00
struct libnet_UnjoinCtx * u = NULL ;
char * cleartext_pwd = NULL ;
char * admin_domain = NULL ;
char * admin_account = NULL ;
WERROR werr ;
2011-02-21 12:25:52 +03:00
struct security_token * token = p - > session_info - > security_token ;
2012-08-04 12:05:51 +04:00
NTSTATUS status ;
DATA_BLOB session_key ;
2016-09-20 20:51:15 +03:00
bool ok ;
2008-02-28 23:55:01 +03:00
2008-03-29 01:39:57 +03:00
if ( ! r - > in . account | | ! r - > in . encrypted_password ) {
2015-12-03 17:24:25 +03:00
return WERR_INVALID_PARAMETER ;
2008-03-29 01:39:57 +03:00
}
2010-10-23 02:58:40 +04:00
if ( ! security_token_has_privilege ( token , SEC_PRIV_MACHINE_ACCOUNT ) & &
2010-05-18 00:04:24 +04:00
! nt_token_check_domain_rid ( token , DOMAIN_RID_ADMINS ) & &
2009-08-06 22:59:32 +04:00
! nt_token_check_sid ( & global_sid_Builtin_Administrators , token ) ) {
2008-02-28 23:55:01 +03:00
DEBUG ( 5 , ( " _wkssvc_NetrUnjoinDomain2: account doesn't have "
" sufficient privileges \n " ) ) ;
return WERR_ACCESS_DENIED ;
}
2012-08-04 12:05:51 +04:00
status = session_extract_session_key ( p - > session_info ,
& session_key ,
KEY_USE_16BYTES ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 5 , ( " _wkssvc_NetrUnjoinDomain2: no session key %s \n " ,
nt_errstr ( status ) ) ) ;
return WERR_NO_USER_SESSION_KEY ;
}
2008-06-24 16:33:31 +04:00
werr = decode_wkssvc_join_password_buffer (
p - > mem_ctx , r - > in . encrypted_password ,
2012-08-04 12:05:51 +04:00
& session_key , & cleartext_pwd ) ;
2008-02-28 23:55:01 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
return werr ;
}
2016-09-20 20:51:15 +03:00
ok = split_domain_user ( p - > mem_ctx ,
r - > in . account ,
& admin_domain ,
& admin_account ) ;
if ( ! ok ) {
2015-12-03 17:24:15 +03:00
return WERR_NOT_ENOUGH_MEMORY ;
2016-09-20 20:51:15 +03:00
}
2008-02-28 23:55:01 +03:00
werr = libnet_init_UnjoinCtx ( p - > mem_ctx , & u ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
return werr ;
}
u - > in . domain_name = lp_realm ( ) ;
u - > in . unjoin_flags = r - > in . unjoin_flags |
WKSSVC_JOIN_FLAGS_JOIN_TYPE ;
u - > in . admin_account = admin_account ;
u - > in . admin_password = cleartext_pwd ;
u - > in . debug = true ;
2008-04-17 01:59:43 +04:00
u - > in . modify_config = lp_config_backend_is_registry ( ) ;
2010-08-07 13:58:48 +04:00
u - > in . msg_ctx = p - > msg_ctx ;
2008-02-28 23:55:01 +03:00
become_root ( ) ;
2011-09-21 19:28:58 +04:00
setenv ( KRB5_ENV_CCNAME , " MEMORY:_wkssvc_NetrUnjoinDomain2 " , 1 ) ;
2008-02-28 23:55:01 +03:00
werr = libnet_Unjoin ( p - > mem_ctx , u ) ;
2011-09-21 19:28:58 +04:00
unsetenv ( KRB5_ENV_CCNAME ) ;
2008-02-28 23:55:01 +03:00
unbecome_root ( ) ;
2008-03-29 01:39:57 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
DEBUG ( 5 , ( " _wkssvc_NetrUnjoinDomain2: libnet_Unjoin failed with: %s \n " ,
u - > out . error_string ? u - > out . error_string :
2008-11-01 19:19:26 +03:00
win_errstr ( werr ) ) ) ;
2008-03-29 01:39:57 +03:00
}
2008-02-28 23:55:01 +03:00
TALLOC_FREE ( u ) ;
return werr ;
2006-09-20 23:26:21 +04:00
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrRenameMachineInDomain2 ( struct pipes_struct * p ,
struct wkssvc_NetrRenameMachineInDomain2 * r )
2006-09-20 23:26:21 +04:00
{
2009-05-08 23:56:17 +04:00
/* for now just return not supported */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrValidateName2 ( struct pipes_struct * p ,
struct wkssvc_NetrValidateName2 * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrGetJoinableOus2 ( struct pipes_struct * p ,
struct wkssvc_NetrGetJoinableOus2 * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
2006-09-20 21:56:50 +04:00
2006-09-20 23:26:21 +04:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrAddAlternateComputerName ( struct pipes_struct * p ,
struct wkssvc_NetrAddAlternateComputerName * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
2006-09-20 21:56:50 +04:00
2006-09-20 23:26:21 +04:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-20 21:56:50 +04:00
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrRemoveAlternateComputerName ( struct pipes_struct * p ,
struct wkssvc_NetrRemoveAlternateComputerName * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
2006-09-20 21:56:50 +04:00
}
2006-09-20 23:26:21 +04:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrSetPrimaryComputername ( struct pipes_struct * p ,
struct wkssvc_NetrSetPrimaryComputername * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 12:27:55 +04:00
WERROR _wkssvc_NetrEnumerateComputerNames ( struct pipes_struct * p ,
struct wkssvc_NetrEnumerateComputerNames * r )
2006-09-20 23:26:21 +04:00
{
/* FIXME: Add implementation code here */
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-20 23:26:21 +04:00
return WERR_NOT_SUPPORTED ;
}