Attempt at fixing bug #283. There however is no solution.
authorGerald Carter <jerry@samba.org>
Thu, 14 Aug 2003 21:14:28 +0000 (21:14 +0000)
committerGerald Carter <jerry@samba.org>
Thu, 14 Aug 2003 21:14:28 +0000 (21:14 +0000)
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 used to be commit 96bc2abfcb0dd0912696fad76e43cb217b33e061)

19 files changed:
source3/Makefile.in
source3/configure.in
source3/include/ntdomain.h
source3/include/rpc_dce.h
source3/include/rpc_ds.h
source3/include/rpc_lsa.h
source3/rpc_server/srv_dfs.c
source3/rpc_server/srv_echo.c
source3/rpc_server/srv_lsa.c
source3/rpc_server/srv_lsa_ds.c [new file with mode: 0644]
source3/rpc_server/srv_lsa_ds_nt.c [new file with mode: 0644]
source3/rpc_server/srv_netlog.c
source3/rpc_server/srv_pipe.c
source3/rpc_server/srv_pipe_hnd.c
source3/rpc_server/srv_reg.c
source3/rpc_server/srv_samr.c
source3/rpc_server/srv_spoolss.c
source3/rpc_server/srv_srvsvc.c
source3/rpc_server/srv_wkssvc.c

index ed98f391efbe1317a20abacf1fc80008063e5312..94c6a5c8d96b249acb66b6ee077cf7eddf177576 100644 (file)
@@ -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 \
index b86eaf8252c6bbc35ed0cae75c862dfd43757c76..5fd35cec38d3b6ba49845481fd2b3d488f92ed95 100644 (file)
@@ -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)
index b6ab4fd0c50ede3795c95a623edc4499c5d7c24a..ccbc190c59d65e67e2142580ef3bf4f035fb2f6c 100644 (file)
@@ -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
@@ -180,7 +191,12 @@ 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. */
 
index c8c47c4fd891b5d77769deed658b65da215ef2bc..2e4a418bb7d186b7510a3f412877d5b273619610 100644 (file)
@@ -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;
 
index 7350fdba1f9a7f52146a57596f067c0230a3d04e..e2622be532c2e2925ce7c8fad55012b1d76a574d 100644 (file)
@@ -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 */
 
 
 /* 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;
index 135fd76d6c9cd21642403a680486d9f49072c0f1..fa49d76c88588c0d2a48581356edc64ed9d23b1c 100644 (file)
 
 /* 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
index 27bb0732b47bc294011e2ff3a44f5c6eb14df8dd..6c35917e618cd5a1f4b5a25295b64b2799cc82f5 100644 (file)
@@ -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));
 }
index 166b6e939d2dea07468058ce1f2b1e17ce8eeb01..909893ce6d4dcbc90ec337b6a22f389d7adb3889 100644 (file)
@@ -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,
index 34812b15d982c4828a8d5742fa28c8fb8b8f76c0..138fb1d7ef9adddf725c323f70257654e937bfb9 100644 (file)
@@ -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 (file)
index 0000000..5996935
--- /dev/null
@@ -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));
+}
diff --git a/source3/rpc_server/srv_lsa_ds_nt.c b/source3/rpc_server/srv_lsa_ds_nt.c
new file mode 100644 (file)
index 0000000..c277086
--- /dev/null
@@ -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;
+}
+
+
+
index d1be2f3723a827608d043f602c89c6c9fd98f204..9c10d86379dff4f3f75d225292ea82440725da34 100644 (file)
@@ -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));
 }
index 11a5c934de4543f533ef033a3ab423b63d1aa283..1c99943a9dcf14588d4eb518c8ab0f6b62db11db 100644 (file)
@@ -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,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,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;
+}
+
+
index 125f6037710b88dd8f59c50eb2f61e74deb69cfe..55def9767324ce9307dbef017d37d2a83e149d20 100644 (file)
@@ -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);
index e1a02103f77d0ef1d13f24ac5bb7a348fa186af3..b780be0aff3c16677989128ed5bfd23539fb9f2d 100644 (file)
@@ -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));
 }
index 86ff039683310472ee49ef228726c90878e974ab..d9624bdff02f184bbe3c429fe86a6c03261d6984 100644 (file)
@@ -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));
 }
index fa0ca8478c6304c5d18be936fbefe95b94f5422f..a903ae902989c644423695f68ce065ba7a74b343 100755 (executable)
@@ -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));
 }
index 0da3cf70dd8b99c11d30f19a90487328c597cbce..9d85088e568beff3a1a6eecac2a0fb5d44b5007a 100644 (file)
@@ -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));
 }
index 856f451779e4c368f2e5783ca3f1aa1cc0eeac36..b5c1af34d9dfe76d66a3b8f867303805ee4f6278 100644 (file)
@@ -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));
 }