-#define OLD_NTDOMAIN 1
/*
- * Unix SMB/Netbios implementation.
- * Version 1.9.
+ * Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1998
* Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
#include "includes.h"
-extern int DEBUGLEVEL;
-
static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len)
{
unsigned char *hash = p->ntlmssp_hash;
BOOL create_next_pdu(pipes_struct *p)
{
RPC_HDR_RESP hdr_resp;
- BOOL auth_verify = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SIGN);
- BOOL auth_seal = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SEAL);
+ BOOL auth_verify = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) != 0);
+ BOOL auth_seal = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL) != 0);
uint32 data_len;
uint32 data_space_available;
uint32 data_len_left;
*/
if(p->fault_state) {
- setup_fault_pdu(p);
+ setup_fault_pdu(p, NT_STATUS(0x1c010002));
return True;
}
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;
* data.
*/
- prs_init( &outgoing_pdu, 0, 4, MARSHALL);
+ prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL);
prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
/* Store the header in the data stream. */
if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) {
DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR.\n"));
+ prs_mem_free(&outgoing_pdu);
return False;
}
if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) {
DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_RESP.\n"));
+ prs_mem_free(&outgoing_pdu);
return False;
}
if(!prs_append_data(&outgoing_pdu, data_from, data_len)) {
DEBUG(0,("create_next_pdu: failed to copy %u bytes of data.\n", (unsigned int)data_len));
+ prs_mem_free(&outgoing_pdu);
return False;
}
(auth_verify ? RPC_HDR_AUTH_LEN : 0), (auth_verify ? 1 : 0));
if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {
DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n"));
+ prs_mem_free(&outgoing_pdu);
return False;
}
}
auth_data = prs_data_p(&outgoing_pdu) + prs_offset(&outgoing_pdu) + 4;
if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, &outgoing_pdu, 0)) {
DEBUG(0,("create_next_pdu: failed to marshall RPC_AUTH_NTLMSSP_CHK.\n"));
+ prs_mem_free(&outgoing_pdu);
return False;
}
NTLMSSPcalc_p(p, (uchar*)auth_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4);
p->out_data.current_pdu_len = p->hdr.frag_len;
p->out_data.current_pdu_sent = 0;
+ prs_mem_free(&outgoing_pdu);
return True;
}
static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlmssp_resp)
{
uchar lm_owf[24];
- uchar nt_owf[24];
+ uchar nt_owf[128];
+ int nt_pw_len;
+ int lm_pw_len;
fstring user_name;
- fstring unix_user_name;
fstring domain;
fstring wks;
- BOOL guest_user = False;
- struct smb_passwd *smb_pass = NULL;
- struct passwd *pass = NULL;
- uchar null_smb_passwd[16];
- uchar *smb_passwd_ptr = NULL;
-
+
+ NTSTATUS nt_status;
+
+ struct auth_context *auth_context = NULL;
+ auth_usersupplied_info *user_info = NULL;
+ auth_serversupplied_info *server_info = NULL;
+
+ uid_t uid;
+ uid_t gid;
+
DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n"));
memset(p->user_name, '\0', sizeof(p->user_name));
- memset(p->unix_user_name, '\0', sizeof(p->unix_user_name));
+ memset(p->pipe_user_name, '\0', sizeof(p->pipe_user_name));
memset(p->domain, '\0', sizeof(p->domain));
memset(p->wks, '\0', sizeof(p->wks));
+ /* Set up for non-authenticated user. */
+ delete_nt_token(&p->pipe_user.nt_user_token);
+ p->pipe_user.ngroups = 0;
+ SAFE_FREE( p->pipe_user.groups);
+
/*
* Setup an empty password for a guest user.
*/
- memset(null_smb_passwd,0,16);
-
/*
* We always negotiate UNICODE.
*/
- if (IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_UNICODE)) {
- fstrcpy(user_name, dos_unistrn2((uint16*)ntlmssp_resp->user, ntlmssp_resp->hdr_usr.str_str_len/2));
- fstrcpy(domain, dos_unistrn2((uint16*)ntlmssp_resp->domain, ntlmssp_resp->hdr_domain.str_str_len/2));
- fstrcpy(wks, dos_unistrn2((uint16*)ntlmssp_resp->wks, ntlmssp_resp->hdr_wks.str_str_len/2));
+ if (p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_UNICODE) {
+ rpcstr_pull(user_name, ntlmssp_resp->user, sizeof(fstring), ntlmssp_resp->hdr_usr.str_str_len*2, 0 );
+ rpcstr_pull(domain, ntlmssp_resp->domain, sizeof(fstring), ntlmssp_resp->hdr_domain.str_str_len*2, 0);
+ rpcstr_pull(wks, ntlmssp_resp->wks, sizeof(fstring), ntlmssp_resp->hdr_wks.str_str_len*2, 0);
} else {
- fstrcpy(user_name, ntlmssp_resp->user);
- fstrcpy(domain, ntlmssp_resp->domain);
- fstrcpy(wks, ntlmssp_resp->wks);
+ pull_ascii_fstring(user_name, ntlmssp_resp->user);
+ pull_ascii_fstring(domain, ntlmssp_resp->domain);
+ pull_ascii_fstring(wks, ntlmssp_resp->wks);
}
DEBUG(5,("user: %s domain: %s wks: %s\n", user_name, domain, wks));
+ nt_pw_len = MIN(sizeof(nt_owf), ntlmssp_resp->hdr_nt_resp.str_str_len);
+ lm_pw_len = MIN(sizeof(lm_owf), ntlmssp_resp->hdr_lm_resp.str_str_len);
+
memcpy(lm_owf, ntlmssp_resp->lm_resp, sizeof(lm_owf));
- memcpy(nt_owf, ntlmssp_resp->nt_resp, sizeof(nt_owf));
+ memcpy(nt_owf, ntlmssp_resp->nt_resp, nt_pw_len);
#ifdef DEBUG_PASSWORD
DEBUG(100,("lm, nt owfs, chal\n"));
dump_data(100, (char *)lm_owf, sizeof(lm_owf));
- dump_data(100, (char *)nt_owf, sizeof(nt_owf));
+ dump_data(100, (char *)nt_owf, nt_pw_len);
dump_data(100, (char *)p->challenge, 8);
#endif
* Allow guest access. Patch from Shirish Kalele <kalele@veritas.com>.
*/
- if((strlen(user_name) == 0) &&
- (ntlmssp_resp->hdr_nt_resp.str_str_len==0))
- {
- guest_user = True;
-
- fstrcpy(unix_user_name, lp_guestaccount(-1));
- DEBUG(100,("Null user in NTLMSSP verification. Using guest = %s\n", unix_user_name));
-
- smb_passwd_ptr = null_smb_passwd;
-
- } else {
-
- /*
- * Pass the user through the NT -> unix user mapping
- * function.
- */
-
- fstrcpy(unix_user_name, user_name);
- (void)map_username(unix_user_name);
+ if (*user_name) {
/*
* Do the length checking only if user is not NULL.
return False;
}
+
+ make_auth_context_fixed(&auth_context, (uchar*)p->challenge);
- /*
- * Find the user in the unix password db.
- */
-
- if(!(pass = Get_Pwnam(unix_user_name,True))) {
- DEBUG(1,("Couldn't find user '%s' in UNIX password database.\n",unix_user_name));
- return(False);
+ if (!make_user_info_netlogon_network(&user_info,
+ user_name, domain, wks,
+ lm_owf, lm_pw_len,
+ nt_owf, nt_pw_len)) {
+ DEBUG(0,("make_user_info_netlogon_network failed! Failing authenticaion.\n"));
+ return False;
}
-
- if(!guest_user) {
-
- become_root(True);
-
- 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);
- 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);
- return False;
- }
-
- unbecome_root(True);
-
- if (smb_pass == NULL) {
- DEBUG(1,("api_pipe_ntlmssp_verify: Couldn't find user '%s' in smb_passwd file.\n",
- unix_user_name));
- return(False);
- }
-
- /* Quit if the account was disabled. */
- if((smb_pass->acct_ctrl & ACB_DISABLED) || !smb_pass->smb_passwd) {
- DEBUG(1,("Account for user '%s' was disabled.\n", unix_user_name));
- return(False);
- }
-
- if(!smb_pass->smb_nt_passwd) {
- DEBUG(1,("Account for user '%s' has no NT password hash.\n", unix_user_name));
- return(False);
- }
-
- smb_passwd_ptr = smb_pass->smb_passwd;
+
+ nt_status = auth_context->check_ntlm_password(auth_context, user_info, &server_info);
+
+ (auth_context->free)(&auth_context);
+ free_user_info(&user_info);
+
+ p->ntlmssp_auth_validated = NT_STATUS_IS_OK(nt_status);
+
+ if (!p->ntlmssp_auth_validated) {
+ DEBUG(1,("api_pipe_ntlmssp_verify: User [%s]\\[%s] from machine %s \
+failed authentication on named pipe %s.\n", domain, user_name, wks, p->name ));
+ free_server_info(&server_info);
+ return False;
}
/*
{
uchar p24[24];
- NTLMSSPOWFencrypt(smb_passwd_ptr, lm_owf, p24);
+ NTLMSSPOWFencrypt(server_info->first_8_lm_hash, lm_owf, p24);
{
unsigned char j = 0;
int ind;
}
fstrcpy(p->user_name, user_name);
- fstrcpy(p->unix_user_name, unix_user_name);
+ fstrcpy(p->pipe_user_name, pdb_get_username(server_info->sam_account));
fstrcpy(p->domain, domain);
fstrcpy(p->wks, wks);
* Store the UNIX credential data (uid/gid pair) in the pipe structure.
*/
- p->uid = pass->pw_uid;
- p->gid = pass->pw_gid;
+ if (!IS_SAM_UNIX_USER(server_info->sam_account)) {
+ DEBUG(0,("Attempted authenticated pipe with invalid user. No uid/gid in SAM_ACCOUNT\n"));
+ free_server_info(&server_info);
+ return False;
+ }
+
+ memcpy(p->session_key, server_info->session_key, sizeof(p->session_key));
+
+ uid = pdb_get_uid(server_info->sam_account);
+ gid = pdb_get_gid(server_info->sam_account);
+
+ p->pipe_user.uid = uid;
+ p->pipe_user.gid = gid;
+
+ /* Set up pipe user group membership. */
+ initialise_groups(p->pipe_user_name, p->pipe_user.uid, p->pipe_user.gid);
+ get_current_groups( &p->pipe_user.ngroups, &p->pipe_user.groups);
+
+ if (server_info->ptok)
+ add_supplementary_nt_login_groups(&p->pipe_user.ngroups, &p->pipe_user.groups, &server_info->ptok);
+
+ /* Create an NT_USER_TOKEN struct for this user. */
+ p->pipe_user.nt_user_token = create_nt_token(p->pipe_user.uid,p->pipe_user.gid,
+ p->pipe_user.ngroups, p->pipe_user.groups,
+ server_info->guest, server_info->ptok);
p->ntlmssp_auth_validated = True;
+
+ pdb_free_sam(&server_info->sam_account);
return True;
}
{
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[] =
{ "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 },
+ { "netdfs", "netdfs" , api_netdfs_rpc },
{ NULL, NULL, NULL }
};
* header and are never sending more than one PDU here.
*/
- prs_init( &outgoing_rpc, 0, 4, MARSHALL);
+ prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL);
prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
if(!smb_io_rpc_hdr("", &nak_hdr, &outgoing_rpc, 0)) {
DEBUG(0,("setup_bind_nak: marshalling of RPC_HDR failed.\n"));
+ prs_mem_free(&outgoing_rpc);
return False;
}
* Now add the reject reason.
*/
- if(!prs_uint16("reject code", &outgoing_rpc, 0, &zero))
+ if(!prs_uint16("reject code", &outgoing_rpc, 0, &zero)) {
+ prs_mem_free(&outgoing_rpc);
return False;
+ }
p->out_data.data_sent_length = 0;
p->out_data.current_pdu_len = prs_offset(&outgoing_rpc);
Marshall a fault pdu.
*******************************************************************/
-BOOL setup_fault_pdu(pipes_struct *p)
+BOOL setup_fault_pdu(pipes_struct *p, NTSTATUS status)
{
prs_struct outgoing_pdu;
RPC_HDR fault_hdr;
* header and are never sending more than one PDU here.
*/
- prs_init( &outgoing_pdu, 0, 4, MARSHALL);
+ prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL);
prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
/*
memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));
- fault_resp.status = 0x1c010002;
+ fault_resp.status = status;
fault_resp.reserved = 0;
/*
if(!smb_io_rpc_hdr("", &fault_hdr, &outgoing_pdu, 0)) {
DEBUG(0,("setup_fault_pdu: marshalling of RPC_HDR failed.\n"));
+ prs_mem_free(&outgoing_pdu);
return False;
}
if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) {
DEBUG(0,("setup_fault_pdu: failed to marshall RPC_HDR_RESP.\n"));
+ prs_mem_free(&outgoing_pdu);
return False;
}
if(!smb_io_rpc_hdr_fault("fault", &fault_resp, &outgoing_pdu, 0)) {
DEBUG(0,("setup_fault_pdu: failed to marshall RPC_HDR_FAULT.\n"));
+ prs_mem_free(&outgoing_pdu);
return False;
}
p->out_data.current_pdu_len = prs_offset(&outgoing_pdu);
p->out_data.current_pdu_sent = 0;
+ prs_mem_free(&outgoing_pdu);
+ 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;
}
* header and are never sending more than one PDU here.
*/
- prs_init( &outgoing_rpc, 0, 4, MARSHALL);
+ prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL);
prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
/*
* auth footers.
*/
- if(!prs_init(&out_hdr_ba, 1024, 4, MARSHALL)) {
+ if(!prs_init(&out_hdr_ba, 1024, p->mem_ctx, MARSHALL)) {
DEBUG(0,("api_pipe_bind_req: malloc out_hdr_ba failed.\n"));
+ prs_mem_free(&outgoing_rpc);
return False;
}
- if(!prs_init(&out_auth, 1024, 4, MARSHALL)) {
+ if(!prs_init(&out_auth, 1024, p->mem_ctx, MARSHALL)) {
DEBUG(0,("pi_pipe_bind_req: malloc out_auth failed.\n"));
+ prs_mem_free(&outgoing_rpc);
prs_mem_free(&out_hdr_ba);
return False;
}
if (p->ntlmssp_auth_requested)
assoc_gid = 0x7a77;
else
- assoc_gid = hdr_rb.bba.assoc_gid;
+ assoc_gid = hdr_rb.bba.assoc_gid ? hdr_rb.bba.assoc_gid : 0x53f0;
/*
* 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.
err_exit:
+ prs_mem_free(&outgoing_rpc);
prs_mem_free(&out_hdr_ba);
prs_mem_free(&out_auth);
return False;
/*
* We always negotiate the following two bits....
*/
- BOOL auth_verify = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SIGN);
- BOOL auth_seal = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SEAL);
+ BOOL auth_verify = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) != 0);
+ BOOL auth_seal = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL) != 0);
int data_len;
int auth_len;
uint32 old_offset;
return True;
}
+/****************************************************************************
+ Return a user struct for a pipe user.
+****************************************************************************/
+
+struct current_user *get_current_user(struct current_user *user, pipes_struct *p)
+{
+ if (p->ntlmssp_auth_validated) {
+ memcpy(user, &p->pipe_user, sizeof(struct current_user));
+ } else {
+ extern struct current_user current_user;
+ memcpy(user, ¤t_user, sizeof(struct current_user));
+ }
+
+ return user;
+}
+
/****************************************************************************
Find the correct RPC function to call for this request.
If the pipe is authenticated then become the correct UNIX user
{
int i = 0;
BOOL ret = False;
- BOOL changed_user_id = False;
if (p->ntlmssp_auth_validated) {
prs_mem_free(&p->out_data.rdata);
return False;
}
-
- changed_user_id = True;
}
for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) {
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);
+ set_current_rpc_talloc(p->mem_ctx);
+ ret = api_fd_commands[i].fn(p);
+ set_current_rpc_talloc(NULL);
}
}
- if(changed_user_id)
- unbecome_authenticated_pipe_user(p);
+ if(p->ntlmssp_auth_validated)
+ unbecome_authenticated_pipe_user();
return ret;
}
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;
+ uint32 offset1, offset2;
+
/* interpret the command */
DEBUG(4,("api_rpcTNP: %s op 0x%x - ", rpc_name, p->hdr_req.opnum));
+ slprintf(name, sizeof(name)-1, "in_%s", rpc_name);
+ 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) {
DEBUG(3,("api_rpcTNP: rpc command: %s\n", api_rpc_cmds[fn_num].name));
* and not put the pipe into fault state. JRA.
*/
DEBUG(4, ("unknown\n"));
- setup_fault_pdu(p);
+ setup_fault_pdu(p, NT_STATUS(0x1c010002));
return True;
}
+ offset1 = prs_offset(&p->out_data.rdata);
+
/* do the actual command */
- if(!api_rpc_cmds[fn_num].fn(rpc_in, &p->out_data.rdata)) {
- DEBUG(0,("api_rpcTNP: %s: failed.\n", rpc_name));
+ if(!api_rpc_cmds[fn_num].fn(p)) {
+ DEBUG(0,("api_rpcTNP: %s: %s failed.\n", rpc_name, api_rpc_cmds[fn_num].name));
prs_mem_free(&p->out_data.rdata);
return False;
}
+ if (p->bad_handle_fault_state) {
+ DEBUG(4,("api_rpcTNP: bad handle fault return.\n"));
+ p->bad_handle_fault_state = False;
+ setup_fault_pdu(p, NT_STATUS(0x1C00001A));
+ return True;
+ }
+
+ slprintf(name, sizeof(name)-1, "out_%s", rpc_name);
+ offset2 = prs_offset(&p->out_data.rdata);
+ prs_set_offset(&p->out_data.rdata, offset1);
+ prs_dump(name, p->hdr_req.opnum, &p->out_data.rdata);
+ prs_set_offset(&p->out_data.rdata, offset2);
+
DEBUG(5,("api_rpcTNP: called %s successfully\n", rpc_name));
+ /* Check for buffer underflow in rpc parsing */
+
+ if ((DEBUGLEVEL >= 10) &&
+ (p->in_data.data.data_offset != p->in_data.data.buffer_size)) {
+ int data_len = p->in_data.data.buffer_size -
+ p->in_data.data.data_offset;
+ char *data;
+
+ data = malloc(data_len);
+
+ DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
+ if (data) {
+ prs_uint8s(False, "", &p->in_data.data, 0, (unsigned char *)data,
+ data_len);
+ SAFE_FREE(data);
+ }
+
+ }
+
return True;
}
-
-#undef OLD_NTDOMAIN