mirror of
https://github.com/samba-team/samba.git
synced 2025-11-23 20:23:50 +03:00
Attempt at fixing bug #283. There however is no solution.
There is a workaround documented in the bug report.
This patch does:
* add server support for the LSA_DS UUID on the lsarpc pipe
* store a list of context_ids/api_structs in the pipe_struct
so that we don't have to lookup the function table for a pipe.
We just match the context_id. Note that a dce/rpc alter_context
does not destroy the previous context so it is possible to
have multiple bindings active on the same pipe. Observed from
standalone win2k sp4 client.
* added server code for DsROleGetPrimaryDOmainInfo() but disabled it
since it causes problems enumerating users and groups from a 2ksp4
domain member in a Samba domain.
This commit is contained in:
@@ -242,6 +242,8 @@ RPC_SAMR_OBJ = rpc_server/srv_samr.o rpc_server/srv_samr_nt.o \
|
||||
|
||||
RPC_REG_OBJ = rpc_server/srv_reg.o rpc_server/srv_reg_nt.o
|
||||
|
||||
RPC_LSA_DS_OBJ = rpc_server/srv_lsa_ds.o rpc_server/srv_lsa_ds_nt.o
|
||||
|
||||
RPC_SVC_OBJ = rpc_server/srv_srvsvc.o rpc_server/srv_srvsvc_nt.o
|
||||
|
||||
RPC_WKS_OBJ = rpc_server/srv_wkssvc.o rpc_server/srv_wkssvc_nt.o
|
||||
@@ -561,7 +563,7 @@ PROTO_OBJ = $(SMBD_OBJ_MAIN) \
|
||||
$(PASSDB_OBJ) $(GROUPDB_OBJ) $(MSDFS_OBJ) \
|
||||
$(READLINE_OBJ) $(PROFILE_OBJ) $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) \
|
||||
$(LIB_SMBD_OBJ) $(SAM_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
|
||||
$(RPC_LSA_OBJ) $(RPC_NETLOG_OBJ) $(RPC_SAMR_OBJ) $(RPC_REG_OBJ) \
|
||||
$(RPC_LSA_OBJ) $(RPC_NETLOG_OBJ) $(RPC_SAMR_OBJ) $(RPC_REG_OBJ) $(RPC_LSA_DS_OBJ) \
|
||||
$(RPC_SVC_OBJ) $(RPC_WKS_OBJ) $(RPC_DFS_OBJ) $(RPC_SPOOLSS_OBJ) \
|
||||
$(RPC_ECHO_OBJ) $(SMBLDAP_OBJ) $(IDMAP_OBJ) libsmb/spnego.o
|
||||
|
||||
@@ -948,6 +950,11 @@ bin/librpc_winreg.@SHLIBEXT@: $(RPC_REG_OBJ)
|
||||
@$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_REG_OBJ) -lc \
|
||||
@SONAMEFLAG@`basename $@`
|
||||
|
||||
bin/librpc_lsa_ds.@SHLIBEXT@: $(RPC_LSA_DS_OBJ)
|
||||
@echo "Linking $@"
|
||||
@$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_LSA_DS_OBJ) -lc \
|
||||
@SONAMEFLAG@`basename $@`
|
||||
|
||||
bin/librpc_spoolss.@SHLIBEXT@: $(RPC_SPOOLSS_OBJ)
|
||||
@echo "Linking $@"
|
||||
@$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_SPOOLSS_OBJ) -lc \
|
||||
|
||||
@@ -284,7 +284,7 @@ DYNEXP=
|
||||
|
||||
dnl Add modules that have to be built by default here
|
||||
dnl These have to be built static:
|
||||
default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin"
|
||||
default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin"
|
||||
|
||||
dnl These are preferably build shared, and static if dlopen() is not available
|
||||
default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly"
|
||||
@@ -3949,6 +3949,7 @@ SMB_SUBSYSTEM(PDB)
|
||||
|
||||
SMB_MODULE(rpc_lsa, \$(RPC_LSA_OBJ), "bin/librpc_lsarpc.$SHLIBEXT", RPC)
|
||||
SMB_MODULE(rpc_reg, \$(RPC_REG_OBJ), "bin/librpc_winreg.$SHLIBEXT", RPC)
|
||||
SMB_MODULE(rpc_lsa_ds, \$(RPC_LSA_DS_OBJ), "bin/librpc_lsa_ds.$SHLIBEXT", RPC)
|
||||
SMB_MODULE(rpc_wks, \$(RPC_WKS_OBJ), "bin/librpc_wkssvc.$SHLIBEXT", RPC)
|
||||
SMB_MODULE(rpc_net, \$(RPC_NETLOG_OBJ), "bin/librpc_NETLOGON.$SHLIBEXT", RPC)
|
||||
SMB_MODULE(rpc_dfs, \$(RPC_DFS_OBJ), "bin/librpc_netdfs.$SHLIBEXT", RPC)
|
||||
|
||||
@@ -165,10 +165,21 @@ struct dcinfo
|
||||
|
||||
};
|
||||
|
||||
typedef struct pipe_rpc_fns {
|
||||
|
||||
struct pipe_rpc_fns *next, *prev;
|
||||
|
||||
/* RPC function table associated with the current rpc_bind (associated by context) */
|
||||
|
||||
struct api_struct *cmds;
|
||||
int n_cmds;
|
||||
uint32 context_id;
|
||||
|
||||
} PIPE_RPC_FNS;
|
||||
|
||||
/*
|
||||
* DCE/RPC-specific samba-internal-specific handling of data on
|
||||
* NamedPipes.
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct pipes_struct
|
||||
@@ -181,6 +192,11 @@ typedef struct pipes_struct
|
||||
fstring name;
|
||||
fstring pipe_srv_name;
|
||||
|
||||
/* linked list of rpc dispatch tables associated
|
||||
with the open rpc contexts */
|
||||
|
||||
PIPE_RPC_FNS *contexts;
|
||||
|
||||
RPC_HDR hdr; /* Incoming RPC header. */
|
||||
RPC_HDR_REQ hdr_req; /* Incoming request header. */
|
||||
|
||||
|
||||
@@ -136,8 +136,8 @@ typedef struct rpc_hdr_info
|
||||
typedef struct rpc_hdr_req_info
|
||||
{
|
||||
uint32 alloc_hint; /* allocation hint - data size (bytes) minus header and tail. */
|
||||
uint16 context_id; /* 0 - presentation context identifier */
|
||||
uint16 opnum; /* opnum */
|
||||
uint16 context_id; /* presentation context identifier */
|
||||
uint16 opnum; /* opnum */
|
||||
|
||||
} RPC_HDR_REQ;
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
/* Opcodes available on PIPE_LSARPC_DS */
|
||||
|
||||
#define DS_GETPRIMDOMINFO 0x00
|
||||
#define DS_NOP 0xFF /* no op -- placeholder */
|
||||
|
||||
/* Opcodes available on PIPE_NETLOGON */
|
||||
|
||||
@@ -35,11 +36,23 @@
|
||||
|
||||
/* macros for RPC's */
|
||||
|
||||
/* DSROLE_PRIMARY_DOMAIN_INFO_BASIC */
|
||||
|
||||
/* flags */
|
||||
|
||||
#define DSROLE_PRIMARY_DS_RUNNING 0x00000001
|
||||
#define DSROLE_PRIMARY_DS_MIXED_MODE 0x00000002
|
||||
#define DSROLE_UPGRADE_IN_PROGRESS 0x00000004
|
||||
#define DSROLE_PRIMARY_DOMAIN_GUID_PRESENT 0x01000000
|
||||
|
||||
/* machine role */
|
||||
|
||||
#define DSROLE_STANDALONE_SRV 2
|
||||
#define DSROLE_DOMAIN_MEMBER_SRV 3
|
||||
#define DSROLE_BDC 4
|
||||
#define DSROLE_PDC 5
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16 machine_role;
|
||||
|
||||
@@ -27,6 +27,12 @@
|
||||
|
||||
/* Opcodes available on PIPE_LSARPC */
|
||||
|
||||
#if 0 /* UNIMPLEMENTED */
|
||||
|
||||
#define LSA_LOOKUPSIDS2 0x39
|
||||
|
||||
#endif
|
||||
|
||||
#define LSA_CLOSE 0x00
|
||||
#define LSA_DELETE 0x01
|
||||
#define LSA_ENUM_PRIVS 0x02
|
||||
|
||||
@@ -157,17 +157,23 @@ static BOOL api_dfs_enum(pipes_struct *p)
|
||||
/*******************************************************************
|
||||
\pipe\netdfs commands
|
||||
********************************************************************/
|
||||
|
||||
NTSTATUS rpc_dfs_init(void)
|
||||
static struct api_struct api_netdfs_cmds[] =
|
||||
{
|
||||
struct api_struct api_netdfs_cmds[] =
|
||||
{
|
||||
{"DFS_EXIST", DFS_EXIST, api_dfs_exist },
|
||||
{"DFS_ADD", DFS_ADD, api_dfs_add },
|
||||
{"DFS_REMOVE", DFS_REMOVE, api_dfs_remove },
|
||||
{"DFS_GET_INFO", DFS_GET_INFO, api_dfs_get_info },
|
||||
{"DFS_ENUM", DFS_ENUM, api_dfs_enum }
|
||||
};
|
||||
};
|
||||
|
||||
void netdfs_get_pipe_fns( struct api_struct **fns, int *n_fns )
|
||||
{
|
||||
*fns = api_netdfs_cmds;
|
||||
*n_fns = sizeof(api_netdfs_cmds) / sizeof(struct api_struct);
|
||||
}
|
||||
|
||||
NTSTATUS rpc_dfs_init(void)
|
||||
{
|
||||
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "netdfs", "netdfs", api_netdfs_cmds,
|
||||
sizeof(api_netdfs_cmds) / sizeof(struct api_struct));
|
||||
}
|
||||
|
||||
@@ -120,14 +120,22 @@ static BOOL api_sink_data(pipes_struct *p)
|
||||
\pipe\rpcecho commands
|
||||
********************************************************************/
|
||||
|
||||
struct api_struct api_echo_cmds[] = {
|
||||
{"ADD_ONE", ECHO_ADD_ONE, api_add_one },
|
||||
{"ECHO_DATA", ECHO_DATA, api_echo_data },
|
||||
{"SOURCE_DATA", ECHO_SOURCE_DATA, api_source_data },
|
||||
{"SINK_DATA", ECHO_SINK_DATA, api_sink_data },
|
||||
};
|
||||
|
||||
|
||||
void echo_get_pipe_fns( struct api_struct **fns, int *n_fns )
|
||||
{
|
||||
*fns = api_echo_cmds;
|
||||
*n_fns = sizeof(api_echo_cmds) / sizeof(struct api_struct);
|
||||
}
|
||||
|
||||
NTSTATUS rpc_echo_init(void)
|
||||
{
|
||||
struct api_struct api_echo_cmds[] = {
|
||||
{"ADD_ONE", ECHO_ADD_ONE, api_add_one },
|
||||
{"ECHO_DATA", ECHO_DATA, api_echo_data },
|
||||
{"SOURCE_DATA", ECHO_SOURCE_DATA, api_source_data },
|
||||
{"SINK_DATA", ECHO_SINK_DATA, api_sink_data },
|
||||
};
|
||||
|
||||
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION,
|
||||
"rpcecho", "rpcecho", api_echo_cmds,
|
||||
|
||||
@@ -644,9 +644,8 @@ static BOOL api_lsa_query_info2(pipes_struct *p)
|
||||
/***************************************************************************
|
||||
\PIPE\ntlsa commands
|
||||
***************************************************************************/
|
||||
NTSTATUS rpc_lsa_init(void)
|
||||
{
|
||||
static const struct api_struct api_lsa_cmds[] =
|
||||
|
||||
static struct api_struct api_lsa_cmds[] =
|
||||
{
|
||||
{ "LSA_OPENPOLICY2" , LSA_OPENPOLICY2 , api_lsa_open_policy2 },
|
||||
{ "LSA_OPENPOLICY" , LSA_OPENPOLICY , api_lsa_open_policy },
|
||||
@@ -671,17 +670,33 @@ static const struct api_struct api_lsa_cmds[] =
|
||||
ADS DC capabilities */
|
||||
{ "LSA_QUERYINFO2" , LSA_QUERYINFO2 , api_lsa_query_info2 }
|
||||
};
|
||||
/*
|
||||
* NOTE: Certain calls can not be enabled if we aren't an ADS DC. Make sure
|
||||
* these calls are always last and that you decrement by the amount of calls
|
||||
* to disable.
|
||||
*/
|
||||
int funcs = sizeof(api_lsa_cmds) / sizeof(struct api_struct);
|
||||
|
||||
if (!(SEC_ADS == lp_security() && ROLE_DOMAIN_PDC == lp_server_role())) {
|
||||
funcs -= 1;
|
||||
}
|
||||
static int count_fns(void)
|
||||
{
|
||||
int funcs = sizeof(api_lsa_cmds) / sizeof(struct api_struct);
|
||||
|
||||
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "lsarpc", "lsass", api_lsa_cmds,
|
||||
funcs);
|
||||
/*
|
||||
* NOTE: Certain calls can not be enabled if we aren't an ADS DC. Make sure
|
||||
* these calls are always last and that you decrement by the amount of calls
|
||||
* to disable.
|
||||
*/
|
||||
if (!(SEC_ADS == lp_security() && ROLE_DOMAIN_PDC == lp_server_role())) {
|
||||
funcs -= 1;
|
||||
}
|
||||
|
||||
return funcs;
|
||||
}
|
||||
void lsa_get_pipe_fns( struct api_struct **fns, int *n_fns )
|
||||
{
|
||||
*fns = api_lsa_cmds;
|
||||
*n_fns = count_fns();
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS rpc_lsa_init(void)
|
||||
{
|
||||
int funcs = count_fns();
|
||||
|
||||
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "lsarpc", "lsass", api_lsa_cmds,
|
||||
funcs);
|
||||
}
|
||||
|
||||
91
source/rpc_server/srv_lsa_ds.c
Normal file
91
source/rpc_server/srv_lsa_ds.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Unix SMB/CIFS implementation.
|
||||
* RPC Pipe client / server routines
|
||||
* Copyright (C) Gerald Carter 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* This is the interface for the registry functions. */
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#undef DBGC_CLASS
|
||||
#define DBGC_CLASS DBGC_RPC_SRV
|
||||
|
||||
/*******************************************************************
|
||||
api_reg_open_entry
|
||||
********************************************************************/
|
||||
|
||||
static BOOL api_dsrole_get_primary_dominfo(pipes_struct *p)
|
||||
{
|
||||
DS_Q_GETPRIMDOMINFO q_u;
|
||||
DS_R_GETPRIMDOMINFO r_u;
|
||||
prs_struct *data = &p->in_data.data;
|
||||
prs_struct *rdata = &p->out_data.rdata;
|
||||
|
||||
ZERO_STRUCT(q_u);
|
||||
ZERO_STRUCT(r_u);
|
||||
|
||||
/* grab the request */
|
||||
if ( !ds_io_q_getprimdominfo("", data, 0, &q_u) )
|
||||
return False;
|
||||
|
||||
/* construct reply. */
|
||||
r_u.status = _dsrole_get_primary_dominfo( p, &q_u, &r_u );
|
||||
|
||||
if ( !ds_io_r_getprimdominfo("", rdata, 0, &r_u) )
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
stub functions for unimplemented RPC
|
||||
*******************************************************************/
|
||||
|
||||
static BOOL api_dsrole_stub( pipes_struct *p )
|
||||
{
|
||||
DEBUG(0,("api_dsrole_stub: Hmmm....didn't know this RPC existsed?!??!\n"));
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
array of \PIPE\lsass (new windows 2000 UUID) operations
|
||||
********************************************************************/
|
||||
static struct api_struct api_lsa_ds_cmds[] = {
|
||||
{ "DS_NOP", DS_NOP, api_dsrole_stub }
|
||||
|
||||
#if 0 /* disabled due to breakage with viewing domain users and groups
|
||||
on a Samba PDC from win2k clients --jerry CIFS 2003 */
|
||||
{ "DS_GETPRIMDOMINFO", DS_GETPRIMDOMINFO, api_dsrole_get_primary_dominfo }
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
void lsa_ds_get_pipe_fns( struct api_struct **fns, int *n_fns )
|
||||
{
|
||||
*fns = api_lsa_ds_cmds;
|
||||
*n_fns = sizeof(api_lsa_ds_cmds) / sizeof(struct api_struct);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS rpc_lsa_ds_init(void)
|
||||
{
|
||||
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "lsa_ds", "lsa_ds", api_lsa_ds_cmds,
|
||||
sizeof(api_lsa_ds_cmds) / sizeof(struct api_struct));
|
||||
}
|
||||
127
source/rpc_server/srv_lsa_ds_nt.c
Normal file
127
source/rpc_server/srv_lsa_ds_nt.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Unix SMB/CIFS implementation.
|
||||
* RPC Pipe client / server routines
|
||||
* Copyright (C) Andrew Tridgell 1992-1997.
|
||||
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997.
|
||||
* Copyright (C) Paul Ashton 1997.
|
||||
* Copyright (C) Jeremy Allison 2001.
|
||||
* Copyright (C) Gerald Carter 2002.
|
||||
*
|
||||
* 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Implementation of registry functions. */
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#undef DBGC_CLASS
|
||||
#define DBGC_CLASS DBGC_RPC_SRV
|
||||
|
||||
/********************************************************************
|
||||
Fill in a DS_DOMINFO_CTR structure
|
||||
********************************************************************/
|
||||
|
||||
static NTSTATUS fill_dsrole_dominfo_basic(TALLOC_CTX *ctx, DSROLE_PRIMARY_DOMAIN_INFO_BASIC **info)
|
||||
{
|
||||
DSROLE_PRIMARY_DOMAIN_INFO_BASIC *basic;
|
||||
const char *netbios_domain;
|
||||
fstring dnsdomain;
|
||||
|
||||
DEBUG(10,("fill_dsrole_dominfo_basic: enter\n"));
|
||||
|
||||
if ( !(basic = talloc_zero(ctx, sizeof(DSROLE_PRIMARY_DOMAIN_INFO_BASIC))) ) {
|
||||
DEBUG(0,("fill_dsrole_dominfo_basic: FATAL error! talloc_xero() failed\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
switch ( lp_server_role() ) {
|
||||
case ROLE_STANDALONE:
|
||||
basic->machine_role = DSROLE_STANDALONE_SRV;
|
||||
break;
|
||||
case ROLE_DOMAIN_MEMBER:
|
||||
basic->machine_role = DSROLE_DOMAIN_MEMBER_SRV;
|
||||
break;
|
||||
case ROLE_DOMAIN_BDC:
|
||||
basic->machine_role = DSROLE_BDC;
|
||||
basic->flags = DSROLE_PRIMARY_DS_RUNNING|DSROLE_PRIMARY_DS_MIXED_MODE;
|
||||
if ( secrets_fetch_domain_guid( lp_workgroup(), &basic->domain_guid ) )
|
||||
basic->flags |= DSROLE_PRIMARY_DOMAIN_GUID_PRESENT;
|
||||
get_mydomname(dnsdomain);
|
||||
strlower_m(dnsdomain);
|
||||
break;
|
||||
case ROLE_DOMAIN_PDC:
|
||||
basic->machine_role = DSROLE_PDC;
|
||||
basic->flags = DSROLE_PRIMARY_DS_RUNNING|DSROLE_PRIMARY_DS_MIXED_MODE;
|
||||
if ( secrets_fetch_domain_guid( lp_workgroup(), &basic->domain_guid ) )
|
||||
basic->flags |= DSROLE_PRIMARY_DOMAIN_GUID_PRESENT;
|
||||
get_mydomname(dnsdomain);
|
||||
strlower_m(dnsdomain);
|
||||
break;
|
||||
}
|
||||
|
||||
basic->unknown = 0x6173; /* seen on the wire; maybe padding */
|
||||
|
||||
/* always set netbios name */
|
||||
|
||||
basic->netbios_ptr = 1;
|
||||
netbios_domain = get_global_sam_name();
|
||||
init_unistr2( &basic->netbios_domain, netbios_domain, strlen(netbios_domain) );
|
||||
|
||||
basic->dnsname_ptr = 1;
|
||||
init_unistr2( &basic->dns_domain, dnsdomain, strlen(dnsdomain) );
|
||||
basic->forestname_ptr = 1;
|
||||
init_unistr2( &basic->forest_domain, dnsdomain, strlen(dnsdomain) );
|
||||
|
||||
|
||||
/* fill in some additional fields if we are a member of an AD domain */
|
||||
|
||||
if ( lp_security() == SEC_ADS ) {
|
||||
/* TODO */
|
||||
;;
|
||||
}
|
||||
|
||||
*info = basic;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Implement the DsroleGetPrimaryDomainInfo() call
|
||||
********************************************************************/
|
||||
|
||||
NTSTATUS _dsrole_get_primary_dominfo(pipes_struct *p, DS_Q_GETPRIMDOMINFO *q_u, DS_R_GETPRIMDOMINFO *r_u)
|
||||
{
|
||||
NTSTATUS result;
|
||||
uint32 level = q_u->level;
|
||||
|
||||
switch ( level ) {
|
||||
|
||||
case DsRolePrimaryDomainInfoBasic:
|
||||
r_u->level = DsRolePrimaryDomainInfoBasic;
|
||||
r_u->ptr = 1;
|
||||
result = fill_dsrole_dominfo_basic( p->mem_ctx, &r_u->info.basic );
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG(0,("_dsrole_get_primary_dominfo: Unsupported info level [%d]!\n",
|
||||
level));
|
||||
result = NT_STATUS_INVALID_LEVEL;
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -320,10 +320,7 @@ static BOOL api_net_logon_ctrl(pipes_struct *p)
|
||||
/*******************************************************************
|
||||
array of \PIPE\NETLOGON operations
|
||||
********************************************************************/
|
||||
|
||||
NTSTATUS rpc_net_init(void)
|
||||
{
|
||||
static struct api_struct api_net_cmds [] =
|
||||
static struct api_struct api_net_cmds [] =
|
||||
{
|
||||
{ "NET_REQCHAL" , NET_REQCHAL , api_net_req_chal },
|
||||
{ "NET_AUTH" , NET_AUTH , api_net_auth },
|
||||
@@ -336,6 +333,14 @@ NTSTATUS rpc_net_init(void)
|
||||
{ "NET_LOGON_CTRL" , NET_LOGON_CTRL , api_net_logon_ctrl }
|
||||
};
|
||||
|
||||
void netlog_get_pipe_fns( struct api_struct **fns, int *n_fns )
|
||||
{
|
||||
*fns = api_net_cmds;
|
||||
*n_fns = sizeof(api_net_cmds) / sizeof(struct api_struct);
|
||||
}
|
||||
|
||||
NTSTATUS rpc_net_init(void)
|
||||
{
|
||||
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "NETLOGON", "lsass", api_net_cmds,
|
||||
sizeof(api_net_cmds) / sizeof(struct api_struct));
|
||||
}
|
||||
|
||||
@@ -713,26 +713,19 @@ BOOL setup_fault_pdu(pipes_struct *p, NTSTATUS status)
|
||||
Used to reject unknown binds from Win2k.
|
||||
*******************************************************************/
|
||||
|
||||
BOOL check_bind_req(char* pipe_name, RPC_IFACE* abstract,
|
||||
RPC_IFACE* transfer)
|
||||
BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract,
|
||||
RPC_IFACE* transfer, uint32 context_id)
|
||||
{
|
||||
extern struct pipe_id_info pipe_names[];
|
||||
char *pipe_name = p->name;
|
||||
int i=0;
|
||||
fstring pname;
|
||||
|
||||
fstrcpy(pname,"\\PIPE\\");
|
||||
fstrcat(pname,pipe_name);
|
||||
|
||||
DEBUG(3,("check_bind_req for %s\n", pname));
|
||||
|
||||
#ifndef SUPPORT_NEW_LSARPC_UUID
|
||||
|
||||
/* check for the first pipe matching the name */
|
||||
|
||||
for ( i=0; pipe_names[i].client_pipe; i++ ) {
|
||||
if ( strequal(pipe_names[i].client_pipe, pname) )
|
||||
break;
|
||||
}
|
||||
#else
|
||||
/* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
|
||||
|
||||
for ( i=0; pipe_names[i].client_pipe; i++ )
|
||||
@@ -743,29 +736,34 @@ BOOL check_bind_req(char* pipe_name, RPC_IFACE* abstract,
|
||||
&& (transfer->version == pipe_names[i].trans_syntax.version)
|
||||
&& (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(RPC_UUID)) == 0) )
|
||||
{
|
||||
struct api_struct *fns = NULL;
|
||||
int n_fns = 0;
|
||||
PIPE_RPC_FNS *context_fns;
|
||||
|
||||
if ( !(context_fns = malloc(sizeof(PIPE_RPC_FNS))) ) {
|
||||
DEBUG(0,("check_bind_req: malloc() failed!\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
/* save the RPC function table associated with this bind */
|
||||
|
||||
get_pipe_fns(i, &fns, &n_fns);
|
||||
|
||||
context_fns->cmds = fns;
|
||||
context_fns->n_cmds = n_fns;
|
||||
context_fns->context_id = context_id;
|
||||
|
||||
/* add to the list of open contexts */
|
||||
|
||||
DLIST_ADD( p->contexts, context_fns );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(pipe_names[i].client_pipe == NULL)
|
||||
return False;
|
||||
|
||||
#ifndef SUPPORT_NEW_LSARPC_UUID
|
||||
/* check the abstract interface */
|
||||
if ( (abstract->version != pipe_names[i].abstr_syntax.version)
|
||||
|| (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(RPC_UUID)) != 0) )
|
||||
{
|
||||
return False;
|
||||
}
|
||||
|
||||
/* check the transfer interface */
|
||||
if ( (transfer->version != pipe_names[i].trans_syntax.version)
|
||||
|| (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(RPC_UUID)) != 0) )
|
||||
{
|
||||
return False;
|
||||
}
|
||||
#endif
|
||||
return True;
|
||||
}
|
||||
|
||||
@@ -861,7 +859,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
|
||||
}
|
||||
|
||||
if (i == rpc_lookup_size) {
|
||||
if (NT_STATUS_IS_ERR(smb_probe_module("rpc", p->name))) {
|
||||
if (NT_STATUS_IS_ERR(smb_probe_module("rpc", p->name))) {
|
||||
DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n",
|
||||
p->name ));
|
||||
if(!setup_bind_nak(p))
|
||||
@@ -1028,7 +1026,8 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
|
||||
unknown to NT4)
|
||||
Needed when adding entries to a DACL from NT5 - SK */
|
||||
|
||||
if(check_bind_req(p->name, &hdr_rb.abstract, &hdr_rb.transfer)) {
|
||||
if(check_bind_req(p, &hdr_rb.abstract, &hdr_rb.transfer, hdr_rb.context_id ))
|
||||
{
|
||||
init_rpc_hdr_ba(&hdr_ba,
|
||||
MAX_PDU_FRAG_LEN,
|
||||
MAX_PDU_FRAG_LEN,
|
||||
@@ -1391,6 +1390,48 @@ struct current_user *get_current_user(struct current_user *user, pipes_struct *p
|
||||
return user;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Find the set of RPC functions associated with this context_id
|
||||
****************************************************************************/
|
||||
|
||||
static PIPE_RPC_FNS* find_pipe_fns_by_context( PIPE_RPC_FNS *list, uint32 context_id )
|
||||
{
|
||||
PIPE_RPC_FNS *fns = NULL;
|
||||
PIPE_RPC_FNS *tmp = NULL;
|
||||
|
||||
if ( !list ) {
|
||||
DEBUG(0,("find_pipe_fns_by_context: ERROR! No context list for pipe!\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (tmp=list; tmp; tmp=tmp->next ) {
|
||||
if ( tmp->context_id == context_id )
|
||||
break;
|
||||
}
|
||||
|
||||
fns = tmp;
|
||||
|
||||
return fns;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
memory cleanup
|
||||
****************************************************************************/
|
||||
|
||||
void free_pipe_rpc_context( PIPE_RPC_FNS *list )
|
||||
{
|
||||
PIPE_RPC_FNS *tmp = list;
|
||||
PIPE_RPC_FNS *tmp2;
|
||||
|
||||
while (tmp) {
|
||||
tmp2 = tmp->next;
|
||||
SAFE_FREE(tmp);
|
||||
tmp = tmp2;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Find the correct RPC function to call for this request.
|
||||
If the pipe is authenticated then become the correct UNIX user
|
||||
@@ -1399,8 +1440,8 @@ struct current_user *get_current_user(struct current_user *user, pipes_struct *p
|
||||
|
||||
BOOL api_pipe_request(pipes_struct *p)
|
||||
{
|
||||
int i = 0;
|
||||
BOOL ret = False;
|
||||
PIPE_RPC_FNS *pipe_fns;
|
||||
|
||||
if (p->ntlmssp_auth_validated) {
|
||||
|
||||
@@ -1412,35 +1453,18 @@ BOOL api_pipe_request(pipes_struct *p)
|
||||
|
||||
DEBUG(5, ("Requested \\PIPE\\%s\n", p->name));
|
||||
|
||||
for (i = 0; i < rpc_lookup_size; i++) {
|
||||
if (strequal(rpc_lookup[i].pipe.clnt, p->name)) {
|
||||
DEBUG(3,("Doing \\PIPE\\%s\n",
|
||||
rpc_lookup[i].pipe.clnt));
|
||||
set_current_rpc_talloc(p->mem_ctx);
|
||||
ret = api_rpcTNP(p, rpc_lookup[i].pipe.clnt,
|
||||
rpc_lookup[i].cmds,
|
||||
rpc_lookup[i].n_cmds);
|
||||
set_current_rpc_talloc(NULL);
|
||||
break;
|
||||
}
|
||||
/* get the set of RPC functions for this context */
|
||||
|
||||
pipe_fns = find_pipe_fns_by_context(p->contexts, p->hdr_req.context_id);
|
||||
|
||||
if ( pipe_fns ) {
|
||||
set_current_rpc_talloc(p->mem_ctx);
|
||||
ret = api_rpcTNP(p, p->name, pipe_fns->cmds, pipe_fns->n_cmds);
|
||||
set_current_rpc_talloc(NULL);
|
||||
}
|
||||
|
||||
|
||||
if (i == rpc_lookup_size) {
|
||||
smb_probe_module("rpc", p->name);
|
||||
|
||||
for (i = 0; i < rpc_lookup_size; i++) {
|
||||
if (strequal(rpc_lookup[i].pipe.clnt, p->name)) {
|
||||
DEBUG(3,("Doing \\PIPE\\%s\n",
|
||||
rpc_lookup[i].pipe.clnt));
|
||||
set_current_rpc_talloc(p->mem_ctx);
|
||||
ret = api_rpcTNP(p, rpc_lookup[i].pipe.clnt,
|
||||
rpc_lookup[i].cmds,
|
||||
rpc_lookup[i].n_cmds);
|
||||
set_current_rpc_talloc(NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
DEBUG(0,("api_pipe_request: No rpc function table associated with context [%d] on pipe [%s]\n",
|
||||
p->hdr_req.context_id, p->name));
|
||||
}
|
||||
|
||||
if(p->ntlmssp_auth_validated)
|
||||
@@ -1529,3 +1553,54 @@ BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name,
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*******************************************************************/
|
||||
|
||||
void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns )
|
||||
{
|
||||
struct api_struct *cmds = NULL;
|
||||
int n_cmds = 0;
|
||||
|
||||
switch ( idx ) {
|
||||
case PI_LSARPC:
|
||||
lsa_get_pipe_fns( &cmds, &n_cmds );
|
||||
break;
|
||||
case PI_LSARPC_DS:
|
||||
lsa_ds_get_pipe_fns( &cmds, &n_cmds );
|
||||
break;
|
||||
case PI_SAMR:
|
||||
samr_get_pipe_fns( &cmds, &n_cmds );
|
||||
break;
|
||||
case PI_NETLOGON:
|
||||
netlog_get_pipe_fns( &cmds, &n_cmds );
|
||||
break;
|
||||
case PI_SRVSVC:
|
||||
srvsvc_get_pipe_fns( &cmds, &n_cmds );
|
||||
break;
|
||||
case PI_WKSSVC:
|
||||
wkssvc_get_pipe_fns( &cmds, &n_cmds );
|
||||
break;
|
||||
case PI_WINREG:
|
||||
reg_get_pipe_fns( &cmds, &n_cmds );
|
||||
break;
|
||||
case PI_SPOOLSS:
|
||||
spoolss_get_pipe_fns( &cmds, &n_cmds );
|
||||
break;
|
||||
case PI_NETDFS:
|
||||
netdfs_get_pipe_fns( &cmds, &n_cmds );
|
||||
break;
|
||||
case PI_ECHO:
|
||||
echo_get_pipe_fns( &cmds, &n_cmds );
|
||||
break;
|
||||
default:
|
||||
DEBUG(0,("get_pipe_fns: Unknown pipe index! [%d]\n", idx));
|
||||
}
|
||||
|
||||
*fns = cmds;
|
||||
*n_fns = n_cmds;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1107,6 +1107,8 @@ static BOOL close_internal_rpc_pipe_hnd(void *np_conn)
|
||||
if (p->mem_ctx)
|
||||
talloc_destroy(p->mem_ctx);
|
||||
|
||||
free_pipe_rpc_context( p->contexts );
|
||||
|
||||
/* Free the handles database. */
|
||||
close_policy_by_pipe(p);
|
||||
|
||||
|
||||
@@ -367,16 +367,12 @@ static BOOL api_reg_save_key(pipes_struct *p)
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
array of \PIPE\reg operations
|
||||
********************************************************************/
|
||||
|
||||
NTSTATUS rpc_reg_init(void)
|
||||
static struct api_struct api_reg_cmds[] =
|
||||
{
|
||||
static struct api_struct api_reg_cmds[] =
|
||||
{
|
||||
{ "REG_CLOSE" , REG_CLOSE , api_reg_close },
|
||||
{ "REG_OPEN_ENTRY" , REG_OPEN_ENTRY , api_reg_open_entry },
|
||||
{ "REG_OPEN_HKCR" , REG_OPEN_HKCR , api_reg_open_hkcr },
|
||||
@@ -390,7 +386,17 @@ NTSTATUS rpc_reg_init(void)
|
||||
{ "REG_ABORT_SHUTDOWN" , REG_ABORT_SHUTDOWN , api_reg_abort_shutdown },
|
||||
{ "REG_UNKNOWN_1A" , REG_UNKNOWN_1A , api_reg_unknown_1a },
|
||||
{ "REG_SAVE_KEY" , REG_SAVE_KEY , api_reg_save_key }
|
||||
};
|
||||
};
|
||||
|
||||
void reg_get_pipe_fns( struct api_struct **fns, int *n_fns )
|
||||
{
|
||||
*fns = api_reg_cmds;
|
||||
*n_fns = sizeof(api_reg_cmds) / sizeof(struct api_struct);
|
||||
}
|
||||
|
||||
NTSTATUS rpc_reg_init(void)
|
||||
{
|
||||
|
||||
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "winreg", "winreg", api_reg_cmds,
|
||||
sizeof(api_reg_cmds) / sizeof(struct api_struct));
|
||||
}
|
||||
|
||||
@@ -1442,10 +1442,8 @@ static BOOL api_samr_set_dom_info(pipes_struct *p)
|
||||
array of \PIPE\samr operations
|
||||
********************************************************************/
|
||||
|
||||
NTSTATUS rpc_samr_init(void)
|
||||
static struct api_struct api_samr_cmds [] =
|
||||
{
|
||||
static struct api_struct api_samr_cmds [] =
|
||||
{
|
||||
{"SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
|
||||
{"SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
|
||||
{"SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
|
||||
@@ -1499,7 +1497,17 @@ NTSTATUS rpc_samr_init(void)
|
||||
{"SAMR_UNKNOWN_2E" , SAMR_UNKNOWN_2E , api_samr_unknown_2e },
|
||||
{"SAMR_SET_DOMAIN_INFO" , SAMR_SET_DOMAIN_INFO , api_samr_set_dom_info },
|
||||
{"SAMR_CONNECT4" , SAMR_CONNECT4 , api_samr_connect4 }
|
||||
};
|
||||
};
|
||||
|
||||
void samr_get_pipe_fns( struct api_struct **fns, int *n_fns )
|
||||
{
|
||||
*fns = api_samr_cmds;
|
||||
*n_fns = sizeof(api_samr_cmds) / sizeof(struct api_struct);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS rpc_samr_init(void)
|
||||
{
|
||||
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "samr", "lsass", api_samr_cmds,
|
||||
sizeof(api_samr_cmds) / sizeof(struct api_struct));
|
||||
}
|
||||
|
||||
@@ -1580,8 +1580,6 @@ static BOOL api_spoolss_replycloseprinter(pipes_struct *p)
|
||||
\pipe\spoolss commands
|
||||
********************************************************************/
|
||||
|
||||
NTSTATUS rpc_spoolss_init(void)
|
||||
{
|
||||
struct api_struct api_spoolss_cmds[] =
|
||||
{
|
||||
{"SPOOLSS_OPENPRINTER", SPOOLSS_OPENPRINTER, api_spoolss_open_printer },
|
||||
@@ -1640,6 +1638,15 @@ NTSTATUS rpc_spoolss_init(void)
|
||||
{"SPOOLSS_REPLYCLOSEPRINTER", SPOOLSS_REPLYCLOSEPRINTER, api_spoolss_replycloseprinter }
|
||||
#endif
|
||||
};
|
||||
|
||||
void spoolss_get_pipe_fns( struct api_struct **fns, int *n_fns )
|
||||
{
|
||||
*fns = api_spoolss_cmds;
|
||||
*n_fns = sizeof(api_spoolss_cmds) / sizeof(struct api_struct);
|
||||
}
|
||||
|
||||
NTSTATUS rpc_spoolss_init(void)
|
||||
{
|
||||
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "spoolss", "spoolss", api_spoolss_cmds,
|
||||
sizeof(api_spoolss_cmds) / sizeof(struct api_struct));
|
||||
}
|
||||
|
||||
@@ -526,10 +526,8 @@ static BOOL api_srv_net_file_set_secdesc(pipes_struct *p)
|
||||
\PIPE\srvsvc commands
|
||||
********************************************************************/
|
||||
|
||||
NTSTATUS rpc_srv_init(void)
|
||||
static struct api_struct api_srv_cmds[] =
|
||||
{
|
||||
static const struct api_struct api_srv_cmds[] =
|
||||
{
|
||||
{ "SRV_NET_CONN_ENUM" , SRV_NET_CONN_ENUM , api_srv_net_conn_enum },
|
||||
{ "SRV_NET_SESS_ENUM" , SRV_NET_SESS_ENUM , api_srv_net_sess_enum },
|
||||
{ "SRV_NET_SHARE_ENUM_ALL" , SRV_NET_SHARE_ENUM_ALL , api_srv_net_share_enum_all },
|
||||
@@ -547,7 +545,17 @@ NTSTATUS rpc_srv_init(void)
|
||||
{ "SRV_NET_NAME_VALIDATE" , SRV_NET_NAME_VALIDATE , api_srv_net_name_validate },
|
||||
{ "SRV_NET_FILE_QUERY_SECDESC", SRV_NET_FILE_QUERY_SECDESC, api_srv_net_file_query_secdesc },
|
||||
{ "SRV_NET_FILE_SET_SECDESC" , SRV_NET_FILE_SET_SECDESC , api_srv_net_file_set_secdesc }
|
||||
};
|
||||
};
|
||||
|
||||
void srvsvc_get_pipe_fns( struct api_struct **fns, int *n_fns )
|
||||
{
|
||||
*fns = api_srv_cmds;
|
||||
*n_fns = sizeof(api_srv_cmds) / sizeof(struct api_struct);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS rpc_srv_init(void)
|
||||
{
|
||||
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "srvsvc", "ntsvcs", api_srv_cmds,
|
||||
sizeof(api_srv_cmds) / sizeof(struct api_struct));
|
||||
}
|
||||
|
||||
@@ -60,12 +60,19 @@ static BOOL api_wks_query_info(pipes_struct *p)
|
||||
\PIPE\wkssvc commands
|
||||
********************************************************************/
|
||||
|
||||
static struct api_struct api_wks_cmds[] =
|
||||
{
|
||||
{ "WKS_Q_QUERY_INFO", WKS_QUERY_INFO, api_wks_query_info }
|
||||
};
|
||||
|
||||
void wkssvc_get_pipe_fns( struct api_struct **fns, int *n_fns )
|
||||
{
|
||||
*fns = api_wks_cmds;
|
||||
*n_fns = sizeof(api_wks_cmds) / sizeof(struct api_struct);
|
||||
}
|
||||
|
||||
NTSTATUS rpc_wks_init(void)
|
||||
{
|
||||
static struct api_struct api_wks_cmds[] =
|
||||
{
|
||||
{ "WKS_Q_QUERY_INFO", WKS_QUERY_INFO, api_wks_query_info }
|
||||
};
|
||||
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "wkssvc", "ntsvcs", api_wks_cmds,
|
||||
sizeof(api_wks_cmds) / sizeof(struct api_struct));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user