summaryrefslogtreecommitdiff
path: root/source3/rpc_server
diff options
context:
space:
mode:
Diffstat (limited to 'source3/rpc_server')
-rw-r--r--source3/rpc_server/srv_dfs.c16
-rw-r--r--source3/rpc_server/srv_dfs_nt.c4
-rw-r--r--source3/rpc_server/srv_echo.c27
-rw-r--r--source3/rpc_server/srv_lsa.c43
-rw-r--r--source3/rpc_server/srv_lsa_ds.c93
-rw-r--r--source3/rpc_server/srv_lsa_ds_nt.c127
-rw-r--r--source3/rpc_server/srv_lsa_nt.c2
-rw-r--r--source3/rpc_server/srv_netlog.c13
-rw-r--r--source3/rpc_server/srv_pipe.c209
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c2
-rw-r--r--source3/rpc_server/srv_reg.c18
-rw-r--r--source3/rpc_server/srv_samr.c49
-rw-r--r--source3/rpc_server/srv_samr_nt.c112
-rwxr-xr-xsource3/rpc_server/srv_spoolss.c13
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c26
-rw-r--r--source3/rpc_server/srv_srvsvc.c16
-rw-r--r--source3/rpc_server/srv_util.c11
-rw-r--r--source3/rpc_server/srv_wkssvc.c15
18 files changed, 624 insertions, 172 deletions
diff --git a/source3/rpc_server/srv_dfs.c b/source3/rpc_server/srv_dfs.c
index 27bb0732b4..6c35917e61 100644
--- a/source3/rpc_server/srv_dfs.c
+++ b/source3/rpc_server/srv_dfs.c
@@ -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));
}
diff --git a/source3/rpc_server/srv_dfs_nt.c b/source3/rpc_server/srv_dfs_nt.c
index eba4eaec75..3470ad99b4 100644
--- a/source3/rpc_server/srv_dfs_nt.c
+++ b/source3/rpc_server/srv_dfs_nt.c
@@ -159,7 +159,7 @@ WERROR _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u,
{
pstring refpath;
pstrcpy(refpath,jn.referral_list[i].alternate_path);
- trim_string(refpath, "\\", "\\");
+ trim_char(refpath, '\\', '\\');
DEBUG(10,("_dfs_remove: refpath: .%s.\n", refpath));
if(strequal(refpath, altpath))
{
@@ -257,7 +257,7 @@ static BOOL init_reply_dfs_info_3(TALLOC_CTX *ctx, struct junction_map* j, DFS_I
struct referral* ref = &(j[i].referral_list[ii]);
pstrcpy(path, ref->alternate_path);
- trim_string(path,"\\","");
+ trim_char(path,'\\','\0');
p = strrchr_m(path,'\\');
if(p==NULL)
{
diff --git a/source3/rpc_server/srv_echo.c b/source3/rpc_server/srv_echo.c
index 166b6e939d..c6cfde07c1 100644
--- a/source3/rpc_server/srv_echo.c
+++ b/source3/rpc_server/srv_echo.c
@@ -120,18 +120,31 @@ static BOOL api_sink_data(pipes_struct *p)
\pipe\rpcecho commands
********************************************************************/
-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 },
+};
+
+
+void echo_get_pipe_fns( struct api_struct **fns, int *n_fns )
{
- 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 },
- };
+ *fns = api_echo_cmds;
+ *n_fns = sizeof(api_echo_cmds) / sizeof(struct api_struct);
+}
+NTSTATUS rpc_echo_init(void)
+{
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION,
"rpcecho", "rpcecho", api_echo_cmds,
sizeof(api_echo_cmds) / sizeof(struct api_struct));
}
+#else /* DEVELOPER */
+
+NTSTATUS rpc_echo_init(void)
+{
+ return NT_STATUS_OK;
+}
#endif /* DEVELOPER */
diff --git a/source3/rpc_server/srv_lsa.c b/source3/rpc_server/srv_lsa.c
index 34812b15d9..138fb1d7ef 100644
--- a/source3/rpc_server/srv_lsa.c
+++ b/source3/rpc_server/srv_lsa.c
@@ -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);
+
+ /*
+ * 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);
+ return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "lsarpc", "lsass", api_lsa_cmds,
+ funcs);
}
diff --git a/source3/rpc_server/srv_lsa_ds.c b/source3/rpc_server/srv_lsa_ds.c
new file mode 100644
index 0000000000..1e75175c2c
--- /dev/null
+++ b/source3/rpc_server/srv_lsa_ds.c
@@ -0,0 +1,93 @@
+/*
+ * 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
+
+#if 0 /* disabled */
+/*******************************************************************
+ 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;
+}
+#endif
+
+/*******************************************************************
+ stub functions for unimplemented RPC
+*******************************************************************/
+
+static BOOL api_dsrole_stub( pipes_struct *p )
+{
+ DEBUG(0,("api_dsrole_stub: Hmmm....didn't know this RPC existed...\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));
+}
diff --git a/source3/rpc_server/srv_lsa_ds_nt.c b/source3/rpc_server/srv_lsa_ds_nt.c
new file mode 100644
index 0000000000..37540a9668
--- /dev/null
+++ b/source3/rpc_server/srv_lsa_ds_nt.c
@@ -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 = NT_STATUS_OK;
+ 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 result;
+}
+
+
+
diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c
index 9eafcb8dc3..330dd727ef 100644
--- a/source3/rpc_server/srv_lsa_nt.c
+++ b/source3/rpc_server/srv_lsa_nt.c
@@ -502,7 +502,7 @@ NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_E
if (!(info->access & POLICY_VIEW_LOCAL_INFORMATION))
return NT_STATUS_ACCESS_DENIED;
- nt_status = secrets_get_trusted_domains(p->mem_ctx, &enum_context, max_num_domains, &num_domains, &trust_doms);
+ nt_status = secrets_get_trusted_domains(p->mem_ctx, (int *)&enum_context, max_num_domains, (int *)&num_domains, &trust_doms);
if (!NT_STATUS_IS_OK(nt_status) &&
!NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES) &&
diff --git a/source3/rpc_server/srv_netlog.c b/source3/rpc_server/srv_netlog.c
index d1be2f3723..9c10d86379 100644
--- a/source3/rpc_server/srv_netlog.c
+++ b/source3/rpc_server/srv_netlog.c
@@ -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));
}
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index 594cb3a9ae..d1fb587d74 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -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))
@@ -878,10 +876,10 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
}
}
- if (i == rpc_lookup_size) {
- DEBUG(0, ("module %s doesn't provide functions for pipe %s!\n", p->name, p->name));
- return False;
- }
+ if (i == rpc_lookup_size) {
+ DEBUG(0, ("module %s doesn't provide functions for pipe %s!\n", p->name, p->name));
+ return False;
+ }
}
/* decode the bind request */
@@ -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,
@@ -1227,10 +1226,10 @@ BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in)
sizeof(p->ntlmssp_hash));
dump_data_pw("Incoming RPC PDU (NTLMSSP sealed)\n",
- data, data_len);
+ (const unsigned char *)data, data_len);
NTLMSSPcalc_p(p, (uchar*)data, data_len);
dump_data_pw("Incoming RPC PDU (NTLMSSP unsealed)\n",
- data, data_len);
+ (const unsigned char *)data, data_len);
crc32 = crc32_calc_buffer(data, data_len);
}
@@ -1392,6 +1391,48 @@ struct current_user *get_current_user(struct current_user *user, pipes_struct *p
}
/****************************************************************************
+ 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
before doing the call.
@@ -1399,9 +1440,9 @@ 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) {
if(!become_authenticated_pipe_user(p)) {
@@ -1411,36 +1452,19 @@ 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,56 @@ 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;
+#ifdef DEVELOPER
+ case PI_ECHO:
+ echo_get_pipe_fns( &cmds, &n_cmds );
+ break;
+#endif
+ default:
+ DEBUG(0,("get_pipe_fns: Unknown pipe index! [%d]\n", idx));
+ }
+
+ *fns = cmds;
+ *n_fns = n_cmds;
+
+ return;
+}
+
+
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index 125f603771..55def97673 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -1106,6 +1106,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);
diff --git a/source3/rpc_server/srv_reg.c b/source3/rpc_server/srv_reg.c
index e1a02103f7..b780be0aff 100644
--- a/source3/rpc_server/srv_reg.c
+++ b/source3/rpc_server/srv_reg.c
@@ -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));
}
diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c
index 86ff039683..a0f62c20fc 100644
--- a/source3/rpc_server/srv_samr.c
+++ b/source3/rpc_server/srv_samr.c
@@ -386,7 +386,7 @@ static BOOL api_samr_chgpasswd_user(pipes_struct *p)
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- /* unknown 38 command */
+ /* change password request */
if (!samr_io_q_chgpasswd_user("", &q_u, data, 0)) {
DEBUG(0,("api_samr_chgpasswd_user: Failed to unmarshall SAMR_Q_CHGPASSWD_USER.\n"));
return False;
@@ -448,13 +448,12 @@ static BOOL api_samr_open_user(pipes_struct *p)
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- /* grab the samr unknown 22 */
if(!samr_io_q_open_user("", &q_u, data, 0)) {
DEBUG(0,("api_samr_open_user: unable to unmarshall SAMR_Q_OPEN_USER.\n"));
return False;
}
- r_u.status = _api_samr_open_user(p, &q_u, &r_u);
+ r_u.status = _samr_open_user(p, &q_u, &r_u);
/* store the response in the SMB stream */
if(!samr_io_r_open_user("", &r_u, rdata, 0)) {
@@ -479,7 +478,6 @@ static BOOL api_samr_query_userinfo(pipes_struct *p)
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- /* grab the samr unknown 24 */
if(!samr_io_q_query_userinfo("", &q_u, data, 0)){
DEBUG(0,("api_samr_query_userinfo: unable to unmarshall SAMR_Q_QUERY_USERINFO.\n"));
return False;
@@ -510,7 +508,6 @@ static BOOL api_samr_query_usergroups(pipes_struct *p)
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- /* grab the samr unknown 32 */
if(!samr_io_q_query_usergroups("", &q_u, data, 0)) {
DEBUG(0,("api_samr_query_usergroups: unable to unmarshall SAMR_Q_QUERY_USERGROUPS.\n"));
return False;
@@ -541,7 +538,6 @@ static BOOL api_samr_query_dom_info(pipes_struct *p)
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- /* grab the samr unknown 8 command */
if(!samr_io_q_query_dom_info("", &q_u, data, 0)) {
DEBUG(0,("api_samr_query_dom_info: unable to unmarshall SAMR_Q_QUERY_DOMAIN_INFO.\n"));
return False;
@@ -579,7 +575,7 @@ static BOOL api_samr_create_user(pipes_struct *p)
return False;
}
- r_u.status=_api_samr_create_user(p, &q_u, &r_u);
+ r_u.status=_samr_create_user(p, &q_u, &r_u);
/* store the response in the SMB stream */
if(!samr_io_r_create_user("", &r_u, rdata, 0)) {
@@ -761,7 +757,7 @@ static BOOL api_samr_open_alias(pipes_struct *p)
return False;
}
- r_u.status=_api_samr_open_alias(p, &q_u, &r_u);
+ r_u.status=_samr_open_alias(p, &q_u, &r_u);
/* store the response in the SMB stream */
if(!samr_io_r_open_alias("", &r_u, rdata, 0)) {
@@ -1347,13 +1343,13 @@ static BOOL api_samr_open_group(pipes_struct *p)
}
/*******************************************************************
- api_samr_unknown_2d
+ api_samr_remove_user_foreign_domain
********************************************************************/
-static BOOL api_samr_unknown_2d(pipes_struct *p)
+static BOOL api_samr_remove_user_foreign_domain(pipes_struct *p)
{
- SAMR_Q_UNKNOWN_2D q_u;
- SAMR_R_UNKNOWN_2D r_u;
+ SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN q_u;
+ SAMR_R_REMOVE_USER_FOREIGN_DOMAIN r_u;
prs_struct *data = &p->in_data.data;
prs_struct *rdata = &p->out_data.rdata;
@@ -1361,15 +1357,15 @@ static BOOL api_samr_unknown_2d(pipes_struct *p)
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- if (!samr_io_q_unknown_2d("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_unknown_2d: unable to unmarshall SAMR_Q_UNKNOWN_2D.\n"));
+ if (!samr_io_q_remove_user_foreign_domain("", &q_u, data, 0)) {
+ DEBUG(0,("api_samr_remove_user_foreign_domain: unable to unmarshall SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN.\n"));
return False;
}
- r_u.status = _samr_unknown_2d(p, &q_u, &r_u);
+ r_u.status = _samr_remove_user_foreign_domain(p, &q_u, &r_u);
- if (!samr_io_r_unknown_2d("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_unknown_2d: unable to marshall SAMR_R_UNKNOWN_2D.\n"));
+ if (!samr_io_r_remove_user_foreign_domain("", &r_u, rdata, 0)) {
+ DEBUG(0,("api_samr_remove_user_foreign_domain: unable to marshall SAMR_R_REMOVE_USER_FOREIGN_DOMAIN.\n"));
return False;
}
@@ -1421,7 +1417,6 @@ static BOOL api_samr_set_dom_info(pipes_struct *p)
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- /* grab the samr unknown 8 command */
if(!samr_io_q_set_domain_info("", &q_u, data, 0)) {
DEBUG(0,("api_samr_set_dom_info: unable to unmarshall SAMR_Q_SET_DOMAIN_INFO.\n"));
return False;
@@ -1442,10 +1437,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 },
@@ -1490,7 +1483,7 @@ NTSTATUS rpc_samr_init(void)
{"SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
{"SAMR_OPEN_GROUP" , SAMR_OPEN_GROUP , api_samr_open_group },
{"SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
- {"SAMR_UNKNOWN_2D" , SAMR_UNKNOWN_2D , api_samr_unknown_2d },
+ {"SAMR_REMOVE_USER_FOREIGN_DOMAIN" , SAMR_REMOVE_USER_FOREIGN_DOMAIN , api_samr_remove_user_foreign_domain },
{"SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain },
{"SAMR_QUERY_SEC_OBJECT" , SAMR_QUERY_SEC_OBJECT , api_samr_query_sec_obj },
@@ -1499,7 +1492,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));
}
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index 14aad5d6f8..7f7b5e8d5e 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -8,6 +8,7 @@
* Copyright (C) Jeremy Allison 2001-2002,
* Copyright (C) Jean François Micouleau 1998-2001,
* Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002.
+ * Copyright (C) Gerald (Jerry) 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
@@ -913,7 +914,6 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM
} else if (sid_equal(sid, get_global_sam_sid()) && !lp_hide_local_users()) {
struct sys_grent *glist;
struct sys_grent *grp;
- struct passwd *pw;
gid_t winbind_gid_low, winbind_gid_high;
BOOL winbind_groups_exist = lp_idmap_gid(&winbind_gid_low, &winbind_gid_high);
@@ -952,7 +952,7 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM
/* Don't return user private groups... */
- if ((pw = Get_Pwnam(smap.nt_name)) != 0) {
+ if (Get_Pwnam(smap.nt_name) != 0) {
DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
continue;
}
@@ -1013,8 +1013,13 @@ static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DO
*p_num_entries = 0;
+ /* access checks for the users were performed higher up. become/unbecome_root()
+ needed for some passdb backends to enumerate groups */
+
+ become_root();
pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
-
+ unbecome_root();
+
num_entries=group_entries-start_idx;
/* limit the number of entries */
@@ -1659,10 +1664,10 @@ NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOK
}
/*******************************************************************
- _api_samr_open_user. Safe - gives out no passwd info.
+ _samr_open_user. Safe - gives out no passwd info.
********************************************************************/
-NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
+NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
{
SAM_ACCOUNT *sampass=NULL;
DOM_SID sid;
@@ -2140,7 +2145,7 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
num_users, num_groups, num_aliases);
break;
case 0x03:
- account_policy_get(AP_TIME_TO_LOGOUT, (int *)&u_logout);
+ account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
unix_to_nt_time_abs(&nt_logout, u_logout);
init_unk_info3(&ctr->info.inf3, nt_logout);
@@ -2181,12 +2186,12 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
}
/*******************************************************************
- _api_samr_create_user
+ _samr_create_user
Create an account, can be either a normal user or a machine.
This funcion will need to be updated for bdc/domain trusts.
********************************************************************/
-NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
+NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
{
SAM_ACCOUNT *sam_pass=NULL;
fstring account;
@@ -2300,12 +2305,12 @@ NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_
int add_ret;
all_string_sub(add_script, "%u", account, sizeof(account));
add_ret = smbrun(add_script,NULL);
- DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
+ DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
}
else /* no add user script -- ask winbindd to do it */
{
if ( !winbind_create_user( account, &new_rid ) ) {
- DEBUG(3,("_api_samr_create_user: winbind_create_user(%s) failed\n",
+ DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
account));
}
}
@@ -2369,6 +2374,7 @@ NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_
NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
{
struct samr_info *info = NULL;
+ uint32 des_access = q_u->access_mask;
/* Access check */
@@ -2386,6 +2392,13 @@ NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CO
if ((info = get_samr_info_by_sid(NULL)) == NULL)
return NT_STATUS_NO_MEMORY;
+ /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
+ was observed from a win98 client trying to enumerate users (when configured
+ user level access control on shares) --jerry */
+
+ se_map_generic( &des_access, &sam_generic_mapping );
+ info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
+
info->status = q_u->unknown_0;
/* get a (unique) handle. open a policy on it. */
@@ -2510,7 +2523,9 @@ NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_
if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
return NT_STATUS_INVALID_HANDLE;
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain"))) {
+ if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
+ SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_lookup_domain")))
+ {
return r_u->status;
}
@@ -2605,7 +2620,7 @@ NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_EN
api_samr_open_alias
********************************************************************/
-NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
+NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
{
DOM_SID sid;
POLICY_HND domain_pol = q_u->dom_pol;
@@ -3773,7 +3788,8 @@ NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAM
/* check if the user exists before trying to delete */
pdb_init_sam(&sam_pass);
if(!pdb_getsampwsid(sam_pass, &user_sid)) {
- DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
+ DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
+ sid_string_static(&user_sid)));
pdb_free_sam(&sam_pass);
return NT_STATUS_NO_SUCH_USER;
}
@@ -4269,13 +4285,75 @@ NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_G
}
/*********************************************************************
- _samr_unknown_2d
+ _samr_remove_user_foreign_domain
*********************************************************************/
-NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
+NTSTATUS _samr_remove_user_foreign_domain(pipes_struct *p,
+ SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN *q_u,
+ SAMR_R_REMOVE_USER_FOREIGN_DOMAIN *r_u)
{
- DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
+ DOM_SID user_sid, dom_sid;
+ SAM_ACCOUNT *sam_pass=NULL;
+ uint32 acc_granted;
+
+ sid_copy( &user_sid, &q_u->sid.sid );
+
+ DEBUG(5,("_samr_remove_user_foreign_domain: removing user [%s]\n",
+ sid_string_static(&user_sid)));
+
+ /* Find the policy handle. Open a policy on it. */
+
+ if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
+ return NT_STATUS_INVALID_HANDLE;
+
+ if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted,
+ STD_RIGHT_DELETE_ACCESS, "_samr_remove_user_foreign_domain")))
+ {
+ return r_u->status;
+ }
+
+ if ( !sid_check_is_in_our_domain(&user_sid) ) {
+ DEBUG(5,("_samr_remove_user_foreign_domain: user not is our domain!\n"));
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ /* check if the user exists before trying to delete */
+
+ pdb_init_sam(&sam_pass);
+
+ if ( !pdb_getsampwsid(sam_pass, &user_sid) ) {
+
+ DEBUG(5,("_samr_remove_user_foreign_domain:User %s doesn't exist.\n",
+ sid_string_static(&user_sid)));
+
+ pdb_free_sam(&sam_pass);
+
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ /*
+ * delete the unix side
+ *
+ * note: we don't check if the delete really happened
+ * as the script is not necessary present
+ * and maybe the sysadmin doesn't want to delete the unix side
+ */
+
+ smb_delete_user(pdb_get_username(sam_pass));
+
+ /* and delete the samba side */
+
+ if ( !pdb_delete_sam_account(sam_pass) ) {
+
+ DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
+ pdb_free_sam(&sam_pass);
+
+ return NT_STATUS_CANNOT_DELETE;
+ }
+
+ pdb_free_sam(&sam_pass);
+
+ return NT_STATUS_OK;
}
/*******************************************************************
diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c
index fa0ca8478c..f846813a40 100755
--- a/source3/rpc_server/srv_spoolss.c
+++ b/source3/rpc_server/srv_spoolss.c
@@ -141,7 +141,7 @@ static BOOL api_spoolss_deleteprinterdata(pipes_struct *p)
return False;
}
- r_u.status = _spoolss_deleteprinterdata( p, &q_u, &r_u);
+ r_u.status = _spoolss_deleteprinterdata( p, &q_u, &r_u );
if (!spoolss_io_r_deleteprinterdata("", &r_u, rdata, 0)) {
DEBUG(0,("spoolss_io_r_deleteprinterdata: unable to marshall SPOOL_R_DELETEPRINTERDATA.\n"));
@@ -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));
}
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 8237298ebb..7159527a7d 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -387,7 +387,6 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
char *cmd = lp_deleteprinter_cmd();
pstring command;
int ret;
- int i;
/* Printer->dev.handlename equals portname equals sharename */
slprintf(command, sizeof(command)-1, "%s \"%s\"", cmd,
@@ -406,7 +405,7 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
/* go ahead and re-read the services immediately */
reload_services( False );
- if ( ( i = lp_servicenumber( Printer->dev.handlename ) ) < 0 )
+ if ( lp_servicenumber( Printer->dev.handlename ) < 0 )
return WERR_ACCESS_DENIED;
}
@@ -957,7 +956,7 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
SPOOL_NOTIFY_INFO_DATA *data;
uint32 data_len = 0;
uint32 id;
- int i, event_index;
+ int i;
/* Is there notification on this handle? */
@@ -980,8 +979,6 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
data = talloc( mem_ctx, msg_group->num_msgs*sizeof(SPOOL_NOTIFY_INFO_DATA) );
ZERO_STRUCTP(data);
- event_index = 0;
-
/* build the array of change notifications */
sending_msg_count = 0;
@@ -2671,6 +2668,8 @@ static BOOL srv_spoolss_replyopenprinter(int snum, const char *printer,
fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
+ ZERO_STRUCT(notify_cli);
+
if(!spoolss_connect_to_client(&notify_cli, client_ip, unix_printer))
return False;
@@ -3753,7 +3752,6 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
int n_services=lp_numservices();
int i;
- uint32 id;
SPOOL_NOTIFY_OPTION *option;
SPOOL_NOTIFY_OPTION_TYPE *option_type;
@@ -3763,7 +3761,6 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
return WERR_BADFID;
option=Printer->notify.option;
- id=1;
info->version=2;
info->data=NULL;
info->count=0;
@@ -6192,12 +6189,9 @@ static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle,
SPOOL_PRINTER_INFO_LEVEL_7 *info7 = info->info_7;
int snum;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
- WERROR result;
DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
- result = WERR_OK;
-
if (!Printer)
return WERR_BADFID;
@@ -7100,7 +7094,6 @@ static void fill_port_2(PORT_INFO_2 *port, const char *name)
init_unistr(&port->port_name, name);
init_unistr(&port->monitor_name, "Local Monitor");
init_unistr(&port->description, "Local Port");
-#define PORT_TYPE_WRITE 1
port->port_type=PORT_TYPE_WRITE;
port->reserved=0x0;
}
@@ -7723,7 +7716,6 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
NT_PRINTER_INFO_LEVEL *printer = NULL;
- uint32 param_index;
uint32 biggest_valuesize;
uint32 biggest_datasize;
uint32 data_len;
@@ -7772,7 +7764,6 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
{
DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
- param_index = 0;
biggest_valuesize = 0;
biggest_datasize = 0;
@@ -8032,6 +8023,9 @@ WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_
unistr2_to_ascii( valuename, value, sizeof(valuename)-1 );
status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename );
+
+ if ( W_ERROR_IS_OK(status) )
+ mod_a_printer( *printer, 2 );
free_a_printer(&printer, 2);
@@ -8895,6 +8889,9 @@ WERROR _spoolss_deleteprinterdataex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATAEX
status = delete_printer_dataex( printer, keyname, valuename );
+ if ( W_ERROR_IS_OK(status) )
+ mod_a_printer( *printer, 2 );
+
free_a_printer(&printer, 2);
return status;
@@ -9186,12 +9183,11 @@ static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
{
pstring path;
pstring long_archi;
- const char *short_archi;
PRINTPROCESSOR_DIRECTORY_1 *info=NULL;
unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1);
- if (!(short_archi = get_short_archi(long_archi)))
+ if (!get_short_archi(long_archi))
return WERR_INVALID_ENVIRONMENT;
if((info=(PRINTPROCESSOR_DIRECTORY_1 *)malloc(sizeof(PRINTPROCESSOR_DIRECTORY_1))) == NULL)
diff --git a/source3/rpc_server/srv_srvsvc.c b/source3/rpc_server/srv_srvsvc.c
index 0da3cf70dd..9d85088e56 100644
--- a/source3/rpc_server/srv_srvsvc.c
+++ b/source3/rpc_server/srv_srvsvc.c
@@ -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));
}
diff --git a/source3/rpc_server/srv_util.c b/source3/rpc_server/srv_util.c
index 03e53118a8..632d381503 100644
--- a/source3/rpc_server/srv_util.c
+++ b/source3/rpc_server/srv_util.c
@@ -307,8 +307,17 @@ BOOL get_domain_user_groups(TALLOC_CTX *ctx, int *numgroups, DOM_GID **pgids, SA
*/
gids = (DOM_GID *)talloc(ctx, sizeof(DOM_GID) * num_entries);
- /* for each group, check if the user is a member of*/
+ /* for each group, check if the user is a member of. Only include groups
+ from this domain */
+
for(i=0; i<num_entries; i++) {
+
+ if ( !sid_check_is_in_our_domain(&map[i].sid) ) {
+ DEBUG(10,("get_domain_user_groups: skipping check of %s since it is not in our domain\n",
+ map[i].nt_name));
+ continue;
+ }
+
if ((grp=getgrgid(map[i].gid)) == NULL) {
/* very weird !!! */
DEBUG(5,("get_domain_user_groups: gid %d doesn't exist anymore !\n", (int)map[i].gid));
diff --git a/source3/rpc_server/srv_wkssvc.c b/source3/rpc_server/srv_wkssvc.c
index 856f451779..b5c1af34d9 100644
--- a/source3/rpc_server/srv_wkssvc.c
+++ b/source3/rpc_server/srv_wkssvc.c
@@ -60,12 +60,19 @@ static BOOL api_wks_query_info(pipes_struct *p)
\PIPE\wkssvc commands
********************************************************************/
-NTSTATUS rpc_wks_init(void)
+static struct api_struct api_wks_cmds[] =
{
- 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)
+{
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "wkssvc", "ntsvcs", api_wks_cmds,
sizeof(api_wks_cmds) / sizeof(struct api_struct));
}