Removed save directory argument to become_root() calls. Probably most of
[samba.git] / source3 / rpc_server / srv_pipe.c
index ebd4f55fcea183c2aeb477207c3db3e66814e0b1..a5d69efd7e8450366d9b37bc46c79f83b09503ff 100644 (file)
@@ -110,7 +110,7 @@ BOOL create_next_pdu(pipes_struct *p)
                p->hdr.flags = 0;
 
        /*
-        * Work out how much we can fit in a sigle PDU.
+        * Work out how much we can fit in a single PDU.
         */
 
        data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
@@ -360,24 +360,24 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm
 
        if(!guest_user) {
 
-               become_root(True);
+               become_root();
 
                if(!(p->ntlmssp_auth_validated = pass_check_smb(unix_user_name, domain,
                                      (uchar*)p->challenge, lm_owf, nt_owf, NULL))) {
                        DEBUG(1,("api_pipe_ntlmssp_verify: User %s\\%s from machine %s \
 failed authentication on named pipe %s.\n", domain, unix_user_name, wks, p->name ));
-                       unbecome_root(True);
+                       unbecome_root();
                        return False;
                }
 
                if(!(smb_pass = getsmbpwnam(unix_user_name))) {
                        DEBUG(1,("api_pipe_ntlmssp_verify: Cannot find user %s in smb passwd database.\n",
                                unix_user_name));
-                       unbecome_root(True);
+                       unbecome_root();
                        return False;
                }
 
-               unbecome_root(True);
+               unbecome_root();
 
                if (smb_pass == NULL) {
                        DEBUG(1,("api_pipe_ntlmssp_verify: Couldn't find user '%s' in smb_passwd file.\n", 
@@ -462,7 +462,7 @@ struct api_cmd
 {
   char * pipe_clnt_name;
   char * pipe_srv_name;
-  BOOL (*fn) (pipes_struct *, prs_struct *);
+  BOOL (*fn) (pipes_struct *);
 };
 
 static struct api_cmd api_fd_commands[] =
@@ -472,10 +472,11 @@ static struct api_cmd api_fd_commands[] =
     { "srvsvc",   "ntsvcs",  api_srvsvc_rpc },
     { "wkssvc",   "ntsvcs",  api_wkssvc_rpc },
     { "NETLOGON", "lsass",   api_netlog_rpc },
-#if 1 /* DISABLED_IN_2_0 JRATEST */
     { "winreg",   "winreg",  api_reg_rpc },
-#endif
     { "spoolss",  "spoolss", api_spoolss_rpc },
+#ifdef WITH_MSDFS
+    { "netdfs",   "netdfs" , api_netdfs_rpc },
+#endif
     { NULL,       NULL,      NULL }
 };
 
@@ -664,6 +665,43 @@ BOOL setup_fault_pdu(pipes_struct *p)
        return True;
 }
 
+/*******************************************************************
+ Ensure a bind request has the correct abstract & transfer interface.
+ Used to reject unknown binds from Win2k.
+*******************************************************************/
+
+BOOL check_bind_req(char* pipe_name, RPC_IFACE* abstract,
+                                       RPC_IFACE* transfer)
+{
+       extern struct pipe_id_info pipe_names[];
+       int i=0;
+       fstring pname;
+       fstrcpy(pname,"\\PIPE\\");
+       fstrcat(pname,pipe_name);
+
+       for(i=0;pipe_names[i].client_pipe; i++) {
+               if(strequal(pipe_names[i].client_pipe, pname))
+                       break;
+       }
+
+       if(pipe_names[i].client_pipe == NULL)
+               return False;
+
+       /* 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;
+
+       return True;
+}
+
 /*******************************************************************
  Respond to a pipe bind request.
 *******************************************************************/
@@ -823,13 +861,29 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
         * Create the bind response struct.
         */
 
-       init_rpc_hdr_ba(&hdr_ba,
+       /* If the requested abstract synt uuid doesn't match our client pipe,
+               reject the bind_ack & set the transfer interface synt to all 0's,
+               ver 0 (observed when NT5 attempts to bind to abstract interfaces
+               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)) {
+               init_rpc_hdr_ba(&hdr_ba,
                        MAX_PDU_FRAG_LEN,
                        MAX_PDU_FRAG_LEN,
                        assoc_gid,
                        ack_pipe_name,
                        0x1, 0x0, 0x0,
                        &hdr_rb.transfer);
+       } else {
+               RPC_IFACE null_interface;
+               ZERO_STRUCT(null_interface);
+               /* Rejection reason: abstract syntax not supported */
+               init_rpc_hdr_ba(&hdr_ba, MAX_PDU_FRAG_LEN,
+                                       MAX_PDU_FRAG_LEN, assoc_gid,
+                                       ack_pipe_name, 0x1, 0x2, 0x1,
+                                       &null_interface);
+       }
 
        /*
         * and marshall it.
@@ -1062,7 +1116,7 @@ BOOL api_pipe_request(pipes_struct *p)
                if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) &&
                    api_fd_commands[i].fn != NULL) {
                        DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i].pipe_clnt_name));
-                       ret = api_fd_commands[i].fn(p, &p->in_data.data);
+                       ret = api_fd_commands[i].fn(p);
                }
        }
 
@@ -1076,8 +1130,8 @@ BOOL api_pipe_request(pipes_struct *p)
  Calls the underlying RPC function for a named pipe.
  ********************************************************************/
 
-BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds,
-                               prs_struct *rpc_in)
+BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, 
+               struct api_struct *api_rpc_cmds)
 {
        int fn_num;
        fstring name;
@@ -1087,7 +1141,7 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds
        DEBUG(4,("api_rpcTNP: %s op 0x%x - ", rpc_name, p->hdr_req.opnum));
 
        slprintf(name, sizeof(name), "in_%s", rpc_name);
-       prs_dump(name, p->hdr_req.opnum, rpc_in);
+       prs_dump(name, p->hdr_req.opnum, &p->in_data.data);
 
        for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++) {
                if (api_rpc_cmds[fn_num].opnum == p->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL) {
@@ -1110,7 +1164,7 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds
        offset1 = prs_offset(&p->out_data.rdata);
 
        /* do the actual command */
-       if(!api_rpc_cmds[fn_num].fn(rpc_in, &p->out_data.rdata)) {
+       if(!api_rpc_cmds[fn_num].fn(p)) {
                DEBUG(0,("api_rpcTNP: %s: failed.\n", rpc_name));
                prs_mem_free(&p->out_data.rdata);
                return False;