mirror of
https://github.com/samba-team/samba.git
synced 2025-02-24 13:57:43 +03:00
a fairly large commit!
This adds support for bigendian rpc in the client. I have installed SUN pcnetlink locally and am using it to test the samba4 rpc code. This allows us to easily find places where we have stuffed up the types (such as 2 uint16 versus a uint32), as testing both big-endian and little-endian easily shows which is correct. I have now used this to fix several bugs like that in the samba4 IDL. In order to make this work I also had to redefine a GUID as a true structure, not a blob. From the pcnetlink wire it is clear that it is indeed defined as a structure (the byte order changes). This required changing lots of Samba code to use a GUID as a structure. I also had to fix the if_version code in dcerpc syntax IDs, as it turns out they are a single uint32 not two uint16s. The big-endian support is a bit ugly at the moment, and breaks the layering in some places. More work is needed, especially on the server side. (This used to be commit bb1af644a5a7b188290ce36232f255da0e5d66d2)
This commit is contained in:
parent
1413faae58
commit
24c22aef90
@ -269,6 +269,9 @@ sub HeaderInterface($)
|
|||||||
|
|
||||||
my $count = 0;
|
my $count = 0;
|
||||||
|
|
||||||
|
$res .= "#ifndef _HEADER_NDR_$interface->{NAME}\n";
|
||||||
|
$res .= "#define _HEADER_NDR_$interface->{NAME}\n\n";
|
||||||
|
|
||||||
if (defined $if_uuid) {
|
if (defined $if_uuid) {
|
||||||
my $name = uc $interface->{NAME};
|
my $name = uc $interface->{NAME};
|
||||||
$res .= "#define DCERPC_$name\_UUID \"$if_uuid\"\n";
|
$res .= "#define DCERPC_$name\_UUID \"$if_uuid\"\n";
|
||||||
@ -297,6 +300,7 @@ sub HeaderInterface($)
|
|||||||
HeaderFunction($d);
|
HeaderFunction($d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$res .= "#endif /* _HEADER_NDR_$interface->{NAME} */\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
|
@ -768,7 +768,6 @@ extern int errno;
|
|||||||
|
|
||||||
#include "mutex.h"
|
#include "mutex.h"
|
||||||
|
|
||||||
#include "librpc/ndr/libndr.h"
|
|
||||||
#include "librpc/rpc/dcerpc.h"
|
#include "librpc/rpc/dcerpc.h"
|
||||||
|
|
||||||
#include "rpc_server/dcerpc_server.h"
|
#include "rpc_server/dcerpc_server.h"
|
||||||
|
@ -116,8 +116,8 @@ typedef struct security_ace_info
|
|||||||
|
|
||||||
/* this stuff may be present when type is XXXX_TYPE_XXXX_OBJECT */
|
/* this stuff may be present when type is XXXX_TYPE_XXXX_OBJECT */
|
||||||
uint32 obj_flags; /* xxxx_ACE_OBJECT_xxxx e.g present/inherited present etc */
|
uint32 obj_flags; /* xxxx_ACE_OBJECT_xxxx e.g present/inherited present etc */
|
||||||
GUID obj_guid; /* object GUID */
|
struct GUID obj_guid; /* object GUID */
|
||||||
GUID inh_guid; /* inherited object GUID */
|
struct GUID inh_guid; /* inherited object GUID */
|
||||||
/* eof object stuff */
|
/* eof object stuff */
|
||||||
|
|
||||||
DOM_SID trustee;
|
DOM_SID trustee;
|
||||||
|
@ -421,7 +421,9 @@ struct vuid_cache {
|
|||||||
#include "smb_acls.h"
|
#include "smb_acls.h"
|
||||||
#include "enums.h"
|
#include "enums.h"
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
|
#include "librpc/gen_ndr/ndr_misc.h"
|
||||||
#include "smb_interfaces.h"
|
#include "smb_interfaces.h"
|
||||||
|
#include "librpc/ndr/libndr.h"
|
||||||
|
|
||||||
typedef struct smb_vfs_handle_struct
|
typedef struct smb_vfs_handle_struct
|
||||||
{
|
{
|
||||||
|
@ -24,10 +24,6 @@ typedef SMB_BIG_UINT large_t;
|
|||||||
|
|
||||||
/* Globally Unique ID */
|
/* Globally Unique ID */
|
||||||
#define GUID_SIZE 16
|
#define GUID_SIZE 16
|
||||||
typedef struct GUID
|
|
||||||
{
|
|
||||||
uint8 info[GUID_SIZE];
|
|
||||||
} GUID;
|
|
||||||
|
|
||||||
/* 64 bit time (100 nanosec) 1601 - cifs6.txt, section 3.5, page 30 */
|
/* 64 bit time (100 nanosec) 1601 - cifs6.txt, section 3.5, page 30 */
|
||||||
typedef struct nttime_info
|
typedef struct nttime_info
|
||||||
@ -946,7 +942,7 @@ union smb_fsinfo {
|
|||||||
large_t quota_soft;
|
large_t quota_soft;
|
||||||
large_t quota_hard;
|
large_t quota_hard;
|
||||||
large_t quota_flags;
|
large_t quota_flags;
|
||||||
GUID guid;
|
struct GUID guid;
|
||||||
char *volume_name;
|
char *volume_name;
|
||||||
char *fs_type;
|
char *fs_type;
|
||||||
} out;
|
} out;
|
||||||
@ -1074,7 +1070,7 @@ union smb_fsinfo {
|
|||||||
enum fsinfo_level level;
|
enum fsinfo_level level;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
GUID guid;
|
struct GUID guid;
|
||||||
large_t unknown[6];
|
large_t unknown[6];
|
||||||
} out;
|
} out;
|
||||||
} objectid_information;
|
} objectid_information;
|
||||||
|
@ -613,24 +613,6 @@ char *sid_binstring(const DOM_SID *sid)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************
|
|
||||||
Print a GUID structure for debugging.
|
|
||||||
*****************************************************************/
|
|
||||||
|
|
||||||
void print_guid(GUID *guid)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
d_printf("%08x-%04x-%04x",
|
|
||||||
IVAL(guid->info, 0), SVAL(guid->info, 4), SVAL(guid->info, 6));
|
|
||||||
d_printf("-%02x%02x-", guid->info[8], guid->info[9]);
|
|
||||||
for (i=10;i<GUID_SIZE;i++)
|
|
||||||
d_printf("%02x", guid->info[i]);
|
|
||||||
d_printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
Check if ACE has OBJECT type.
|
Check if ACE has OBJECT type.
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
* UUID server routines
|
* UUID server routines
|
||||||
* Copyright (C) Theodore Ts'o 1996, 1997,
|
* Copyright (C) Theodore Ts'o 1996, 1997,
|
||||||
* Copyright (C) Jim McDonough 2002.
|
* Copyright (C) Jim McDonough 2002.
|
||||||
|
* Copyright (C) Andrew Tridgell 2003.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -21,52 +22,9 @@
|
|||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
|
||||||
/*
|
void uuid_generate_random(struct GUID *out)
|
||||||
* Offset between 15-Oct-1582 and 1-Jan-70
|
|
||||||
*/
|
|
||||||
#define TIME_OFFSET_HIGH 0x01B21DD2
|
|
||||||
#define TIME_OFFSET_LOW 0x13814000
|
|
||||||
|
|
||||||
struct uuid {
|
|
||||||
uint32 time_low;
|
|
||||||
uint16 time_mid;
|
|
||||||
uint16 time_hi_and_version;
|
|
||||||
uint8 clock_seq[2];
|
|
||||||
uint8 node[6];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static void uuid_pack(const struct uuid *uu, GUID *ptr)
|
|
||||||
{
|
{
|
||||||
uint8 *out = ptr->info;
|
generate_random_buffer(out, sizeof(struct GUID), False);
|
||||||
|
out->clock_seq[0] = (out->clock_seq[0] & 0x3F) | 0x80;
|
||||||
SIVAL(out, 0, uu->time_low);
|
out->time_hi_and_version = (out->time_hi_and_version & 0x0FFF) | 0x4000;
|
||||||
SSVAL(out, 4, uu->time_mid);
|
|
||||||
SSVAL(out, 6, uu->time_hi_and_version);
|
|
||||||
memcpy(out+8, uu->clock_seq, 2);
|
|
||||||
memcpy(out+10, uu->node, 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void uuid_unpack(const GUID in, struct uuid *uu)
|
|
||||||
{
|
|
||||||
const uint8 *ptr = in.info;
|
|
||||||
|
|
||||||
uu->time_low = IVAL(ptr, 0);
|
|
||||||
uu->time_mid = SVAL(ptr, 4);
|
|
||||||
uu->time_hi_and_version = SVAL(ptr, 6);
|
|
||||||
memcpy(uu->clock_seq, ptr+8, 2);
|
|
||||||
memcpy(uu->node, ptr+10, 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uuid_generate_random(GUID *out)
|
|
||||||
{
|
|
||||||
GUID tmp;
|
|
||||||
struct uuid uu;
|
|
||||||
|
|
||||||
generate_random_buffer(tmp.info, sizeof(tmp.info), True);
|
|
||||||
uuid_unpack(tmp, &uu);
|
|
||||||
|
|
||||||
uu.clock_seq[0] = (uu.clock_seq[0] & 0x3F) | 0x80;
|
|
||||||
uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000;
|
|
||||||
uuid_pack(&uu, out);
|
|
||||||
}
|
}
|
||||||
|
@ -259,7 +259,8 @@ NTSTATUS smb_raw_fsinfo_recv(struct cli_request *req,
|
|||||||
|
|
||||||
case RAW_QFS_OBJECTID_INFORMATION:
|
case RAW_QFS_OBJECTID_INFORMATION:
|
||||||
QFS_CHECK_SIZE(64);
|
QFS_CHECK_SIZE(64);
|
||||||
memcpy(fsinfo->objectid_information.out.guid.info, blob.data, GUID_SIZE);
|
status = ndr_pull_struct_blob(&blob, mem_ctx, &fsinfo->objectid_information.out.guid,
|
||||||
|
(ndr_pull_flags_fn_t)ndr_pull_GUID);
|
||||||
for (i=0;i<6;i++) {
|
for (i=0;i<6;i++) {
|
||||||
fsinfo->objectid_information.out.unknown[i] = BVAL(blob.data, 16 + i*8);
|
fsinfo->objectid_information.out.unknown[i] = BVAL(blob.data, 16 + i*8);
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,7 @@ interface dcerpc
|
|||||||
{
|
{
|
||||||
typedef [public] struct {
|
typedef [public] struct {
|
||||||
GUID uuid;
|
GUID uuid;
|
||||||
uint16 major_version;
|
uint32 if_version;
|
||||||
uint16 minor_version;
|
|
||||||
} dcerpc_syntax_id;
|
} dcerpc_syntax_id;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -167,6 +166,7 @@ interface dcerpc
|
|||||||
const uint8 DCERPC_PFC_FLAG_NOCALL = 0x20;
|
const uint8 DCERPC_PFC_FLAG_NOCALL = 0x20;
|
||||||
|
|
||||||
/* these offsets are needed by the signing code */
|
/* these offsets are needed by the signing code */
|
||||||
|
const uint8 DCERPC_DREP_OFFSET = 4;
|
||||||
const uint8 DCERPC_FRAG_LEN_OFFSET = 8;
|
const uint8 DCERPC_FRAG_LEN_OFFSET = 8;
|
||||||
const uint8 DCERPC_AUTH_LEN_OFFSET = 10;
|
const uint8 DCERPC_AUTH_LEN_OFFSET = 10;
|
||||||
|
|
||||||
|
@ -8,6 +8,14 @@
|
|||||||
interface misc
|
interface misc
|
||||||
{
|
{
|
||||||
|
|
||||||
|
typedef [public,noprint] struct {
|
||||||
|
uint32 time_low;
|
||||||
|
uint16 time_mid;
|
||||||
|
uint16 time_hi_and_version;
|
||||||
|
uint8 clock_seq[2];
|
||||||
|
uint8 node[6];
|
||||||
|
} GUID;
|
||||||
|
|
||||||
/* a domain SID. Note that unlike Samba3 this contains a pointer,
|
/* a domain SID. Note that unlike Samba3 this contains a pointer,
|
||||||
so you can't copy them using assignment */
|
so you can't copy them using assignment */
|
||||||
typedef [public,noprint] struct {
|
typedef [public,noprint] struct {
|
||||||
|
@ -22,6 +22,12 @@
|
|||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
|
||||||
|
#define NDR_BE(ndr) ((ndr)->flags & LIBNDR_FLAG_BIGENDIAN)
|
||||||
|
#define NDR_SVAL(ndr, ofs) (NDR_BE(ndr)?RSVAL(ndr->data,ofs):SVAL(ndr->data,ofs))
|
||||||
|
#define NDR_IVAL(ndr, ofs) (NDR_BE(ndr)?RIVAL(ndr->data,ofs):IVAL(ndr->data,ofs))
|
||||||
|
#define NDR_SSVAL(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSSVAL(ndr->data,ofs,v); } else SSVAL(ndr->data,ofs,v); } while (0)
|
||||||
|
#define NDR_SIVAL(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSIVAL(ndr->data,ofs,v); } else SIVAL(ndr->data,ofs,v); } while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
parse a uint8
|
parse a uint8
|
||||||
*/
|
*/
|
||||||
@ -41,7 +47,7 @@ NTSTATUS ndr_pull_uint16(struct ndr_pull *ndr, uint16 *v)
|
|||||||
{
|
{
|
||||||
NDR_PULL_ALIGN(ndr, 2);
|
NDR_PULL_ALIGN(ndr, 2);
|
||||||
NDR_PULL_NEED_BYTES(ndr, 2);
|
NDR_PULL_NEED_BYTES(ndr, 2);
|
||||||
*v = SVAL(ndr->data, ndr->offset);
|
*v = NDR_SVAL(ndr, ndr->offset);
|
||||||
ndr->offset += 2;
|
ndr->offset += 2;
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
@ -54,7 +60,7 @@ NTSTATUS ndr_pull_uint32(struct ndr_pull *ndr, uint32 *v)
|
|||||||
{
|
{
|
||||||
NDR_PULL_ALIGN(ndr, 4);
|
NDR_PULL_ALIGN(ndr, 4);
|
||||||
NDR_PULL_NEED_BYTES(ndr, 4);
|
NDR_PULL_NEED_BYTES(ndr, 4);
|
||||||
*v = IVAL(ndr->data, ndr->offset);
|
*v = NDR_IVAL(ndr, ndr->offset);
|
||||||
ndr->offset += 4;
|
ndr->offset += 4;
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
@ -66,8 +72,8 @@ NTSTATUS ndr_pull_HYPER_T(struct ndr_pull *ndr, HYPER_T *v)
|
|||||||
{
|
{
|
||||||
NDR_PULL_ALIGN(ndr, 8);
|
NDR_PULL_ALIGN(ndr, 8);
|
||||||
NDR_PULL_NEED_BYTES(ndr, 8);
|
NDR_PULL_NEED_BYTES(ndr, 8);
|
||||||
v->low = IVAL(ndr->data, ndr->offset);
|
v->low = NDR_IVAL(ndr, ndr->offset);
|
||||||
v->high = IVAL(ndr->data, ndr->offset+4);
|
v->high = NDR_IVAL(ndr, ndr->offset+4);
|
||||||
ndr->offset += 8;
|
ndr->offset += 8;
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
@ -173,18 +179,6 @@ NTSTATUS ndr_pull_array_uint32(struct ndr_pull *ndr, int ndr_flags, uint32 *data
|
|||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
parse a GUID
|
|
||||||
*/
|
|
||||||
NTSTATUS ndr_pull_GUID(struct ndr_pull *ndr, int ndr_flags, GUID *guid)
|
|
||||||
{
|
|
||||||
if (ndr_flags & NDR_SCALARS) {
|
|
||||||
return ndr_pull_bytes(ndr, guid->info, GUID_SIZE);
|
|
||||||
}
|
|
||||||
return NT_STATUS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
push a uint8
|
push a uint8
|
||||||
*/
|
*/
|
||||||
@ -203,7 +197,7 @@ NTSTATUS ndr_push_uint16(struct ndr_push *ndr, uint16 v)
|
|||||||
{
|
{
|
||||||
NDR_PUSH_ALIGN(ndr, 2);
|
NDR_PUSH_ALIGN(ndr, 2);
|
||||||
NDR_PUSH_NEED_BYTES(ndr, 2);
|
NDR_PUSH_NEED_BYTES(ndr, 2);
|
||||||
SSVAL(ndr->data, ndr->offset, v);
|
NDR_SSVAL(ndr, ndr->offset, v);
|
||||||
ndr->offset += 2;
|
ndr->offset += 2;
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
@ -215,7 +209,7 @@ NTSTATUS ndr_push_uint32(struct ndr_push *ndr, uint32 v)
|
|||||||
{
|
{
|
||||||
NDR_PUSH_ALIGN(ndr, 4);
|
NDR_PUSH_ALIGN(ndr, 4);
|
||||||
NDR_PUSH_NEED_BYTES(ndr, 4);
|
NDR_PUSH_NEED_BYTES(ndr, 4);
|
||||||
SIVAL(ndr->data, ndr->offset, v);
|
NDR_SIVAL(ndr, ndr->offset, v);
|
||||||
ndr->offset += 4;
|
ndr->offset += 4;
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
@ -227,8 +221,8 @@ NTSTATUS ndr_push_HYPER_T(struct ndr_push *ndr, HYPER_T v)
|
|||||||
{
|
{
|
||||||
NDR_PUSH_ALIGN(ndr, 8);
|
NDR_PUSH_ALIGN(ndr, 8);
|
||||||
NDR_PUSH_NEED_BYTES(ndr, 8);
|
NDR_PUSH_NEED_BYTES(ndr, 8);
|
||||||
SIVAL(ndr->data, ndr->offset, v.low);
|
NDR_SIVAL(ndr, ndr->offset, v.low);
|
||||||
SIVAL(ndr->data, ndr->offset+4, v.high);
|
NDR_SIVAL(ndr, ndr->offset+4, v.high);
|
||||||
ndr->offset += 8;
|
ndr->offset += 8;
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
@ -581,17 +575,6 @@ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
|
|||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
push a GUID
|
|
||||||
*/
|
|
||||||
NTSTATUS ndr_push_GUID(struct ndr_push *ndr, int ndr_flags, GUID *guid)
|
|
||||||
{
|
|
||||||
if (ndr_flags & NDR_SCALARS) {
|
|
||||||
return ndr_push_bytes(ndr, guid->info, GUID_SIZE);
|
|
||||||
}
|
|
||||||
return NT_STATUS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
push a NTTIME
|
push a NTTIME
|
||||||
*/
|
*/
|
||||||
@ -770,25 +753,24 @@ NTSTATUS GUID_from_string(const char *s, struct GUID *guid)
|
|||||||
{
|
{
|
||||||
uint32 time_low;
|
uint32 time_low;
|
||||||
uint32 time_mid, time_hi_and_version;
|
uint32 time_mid, time_hi_and_version;
|
||||||
uint32 clock_seq_hi_and_reserved;
|
uint32 clock_seq[2];
|
||||||
uint32 clock_seq_low;
|
|
||||||
uint32 node[6];
|
uint32 node[6];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (11 != sscanf(s, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
if (11 != sscanf(s, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||||
&time_low, &time_mid, &time_hi_and_version,
|
&time_low, &time_mid, &time_hi_and_version,
|
||||||
&clock_seq_hi_and_reserved, &clock_seq_low,
|
&clock_seq[0], &clock_seq[1],
|
||||||
&node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
|
&node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
|
||||||
return NT_STATUS_INVALID_PARAMETER;
|
return NT_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
SIVAL(guid->info, 0, time_low);
|
guid->time_low = time_low;
|
||||||
SSVAL(guid->info, 4, time_mid);
|
guid->time_mid = time_mid;
|
||||||
SSVAL(guid->info, 6, time_hi_and_version);
|
guid->time_hi_and_version = time_hi_and_version;
|
||||||
SCVAL(guid->info, 8, clock_seq_hi_and_reserved);
|
guid->clock_seq[0] = clock_seq[0];
|
||||||
SCVAL(guid->info, 9, clock_seq_low);
|
guid->clock_seq[1] = clock_seq[1];
|
||||||
for (i=0;i<6;i++) {
|
for (i=0;i<6;i++) {
|
||||||
SCVAL(guid->info, 10 + i, node[i]);
|
guid->node[i] = node[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
@ -801,12 +783,13 @@ const char *GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid)
|
|||||||
{
|
{
|
||||||
return talloc_asprintf(mem_ctx,
|
return talloc_asprintf(mem_ctx,
|
||||||
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||||
IVAL(guid->info, 0), SVAL(guid->info, 4),
|
guid->time_low, guid->time_mid,
|
||||||
SVAL(guid->info, 6),
|
guid->time_hi_and_version,
|
||||||
guid->info[8], guid->info[9],
|
guid->clock_seq[0],
|
||||||
guid->info[10], guid->info[11],
|
guid->clock_seq[1],
|
||||||
guid->info[12], guid->info[13],
|
guid->node[0], guid->node[1],
|
||||||
guid->info[14], guid->info[15]);
|
guid->node[2], guid->node[3],
|
||||||
|
guid->node[4], guid->node[5]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ndr_print_GUID(struct ndr_print *ndr, const char *name, const struct GUID *guid)
|
void ndr_print_GUID(struct ndr_print *ndr, const char *name, const struct GUID *guid)
|
||||||
|
@ -64,6 +64,35 @@ void dcerpc_pipe_close(struct dcerpc_pipe *p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* we need to be able to get/set the fragment length without doing a full
|
||||||
|
decode */
|
||||||
|
void dcerpc_set_frag_length(DATA_BLOB *blob, uint16 v)
|
||||||
|
{
|
||||||
|
if (CVAL(blob->data,DCERPC_DREP_OFFSET) & 0x10) {
|
||||||
|
SSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET, v);
|
||||||
|
} else {
|
||||||
|
RSSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 dcerpc_get_frag_length(DATA_BLOB *blob)
|
||||||
|
{
|
||||||
|
if (CVAL(blob->data,DCERPC_DREP_OFFSET) & 0x10) {
|
||||||
|
return SVAL(blob->data, DCERPC_FRAG_LEN_OFFSET);
|
||||||
|
} else {
|
||||||
|
return RSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dcerpc_set_auth_length(DATA_BLOB *blob, uint16 v)
|
||||||
|
{
|
||||||
|
if (CVAL(blob->data,DCERPC_DREP_OFFSET) & 0x10) {
|
||||||
|
SSVAL(blob->data, DCERPC_AUTH_LEN_OFFSET, v);
|
||||||
|
} else {
|
||||||
|
RSSVAL(blob->data, DCERPC_AUTH_LEN_OFFSET, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
parse a data blob into a dcerpc_packet structure. This handles both
|
parse a data blob into a dcerpc_packet structure. This handles both
|
||||||
@ -79,6 +108,10 @@ static NTSTATUS dcerpc_pull(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
|
|||||||
return NT_STATUS_NO_MEMORY;
|
return NT_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! (CVAL(blob, DCERPC_DREP_OFFSET) & 0x10)) {
|
||||||
|
ndr->flags |= DCERPC_PULL_BIGENDIAN;
|
||||||
|
}
|
||||||
|
|
||||||
return ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
|
return ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,6 +137,10 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
|
|||||||
return NT_STATUS_NO_MEMORY;
|
return NT_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! (CVAL(blob, DCERPC_DREP_OFFSET) & 0x10)) {
|
||||||
|
ndr->flags |= DCERPC_PULL_BIGENDIAN;
|
||||||
|
}
|
||||||
|
|
||||||
/* pull the basic packet */
|
/* pull the basic packet */
|
||||||
status = ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
|
status = ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
@ -132,6 +169,10 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
|
|||||||
return NT_STATUS_NO_MEMORY;
|
return NT_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! (CVAL(blob, DCERPC_DREP_OFFSET) & 0x10)) {
|
||||||
|
ndr->flags |= DCERPC_PULL_BIGENDIAN;
|
||||||
|
}
|
||||||
|
|
||||||
status = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, &auth);
|
status = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, &auth);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
return status;
|
return status;
|
||||||
@ -184,7 +225,7 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
|
|||||||
|
|
||||||
/* non-signed packets are simpler */
|
/* non-signed packets are simpler */
|
||||||
if (!p->auth_info || !p->ntlmssp_state) {
|
if (!p->auth_info || !p->ntlmssp_state) {
|
||||||
return dcerpc_push_auth(blob, mem_ctx, pkt, p->auth_info);
|
return dcerpc_push_auth(blob, mem_ctx, pkt, p->auth_info, p->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
ndr = ndr_push_init_ctx(mem_ctx);
|
ndr = ndr_push_init_ctx(mem_ctx);
|
||||||
@ -192,6 +233,10 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
|
|||||||
return NT_STATUS_NO_MEMORY;
|
return NT_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p->flags & DCERPC_PUSH_BIGENDIAN) {
|
||||||
|
ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
|
||||||
|
}
|
||||||
|
|
||||||
status = ndr_push_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
|
status = ndr_push_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
return status;
|
return status;
|
||||||
@ -242,8 +287,8 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
|
|||||||
/* fill in the fragment length and auth_length, we can't fill
|
/* fill in the fragment length and auth_length, we can't fill
|
||||||
in these earlier as we don't know the signature length (it
|
in these earlier as we don't know the signature length (it
|
||||||
could be variable length) */
|
could be variable length) */
|
||||||
SSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET, blob->length);
|
dcerpc_set_frag_length(blob, blob->length);
|
||||||
SSVAL(blob->data, DCERPC_AUTH_LEN_OFFSET, p->auth_info->credentials.length);
|
dcerpc_set_auth_length(blob, p->auth_info->credentials.length);
|
||||||
|
|
||||||
data_blob_free(&p->auth_info->credentials);
|
data_blob_free(&p->auth_info->credentials);
|
||||||
|
|
||||||
@ -254,11 +299,15 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
|
|||||||
/*
|
/*
|
||||||
fill in the fixed values in a dcerpc header
|
fill in the fixed values in a dcerpc header
|
||||||
*/
|
*/
|
||||||
static void init_dcerpc_hdr(struct dcerpc_packet *pkt)
|
static void init_dcerpc_hdr(struct dcerpc_pipe *p, struct dcerpc_packet *pkt)
|
||||||
{
|
{
|
||||||
pkt->rpc_vers = 5;
|
pkt->rpc_vers = 5;
|
||||||
pkt->rpc_vers_minor = 0;
|
pkt->rpc_vers_minor = 0;
|
||||||
pkt->drep[0] = 0x10; /* Little endian */
|
if (p->flags & DCERPC_PUSH_BIGENDIAN) {
|
||||||
|
pkt->drep[0] = 0;
|
||||||
|
} else {
|
||||||
|
pkt->drep[0] = 0x10;
|
||||||
|
}
|
||||||
pkt->drep[1] = 0;
|
pkt->drep[1] = 0;
|
||||||
pkt->drep[2] = 0;
|
pkt->drep[2] = 0;
|
||||||
pkt->drep[3] = 0;
|
pkt->drep[3] = 0;
|
||||||
@ -281,7 +330,7 @@ NTSTATUS dcerpc_bind(struct dcerpc_pipe *p,
|
|||||||
DATA_BLOB blob;
|
DATA_BLOB blob;
|
||||||
struct dcerpc_syntax_id tsyntax;
|
struct dcerpc_syntax_id tsyntax;
|
||||||
|
|
||||||
init_dcerpc_hdr(&pkt);
|
init_dcerpc_hdr(p, &pkt);
|
||||||
|
|
||||||
pkt.ptype = DCERPC_PKT_BIND;
|
pkt.ptype = DCERPC_PKT_BIND;
|
||||||
pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
|
pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
|
||||||
@ -304,7 +353,7 @@ NTSTATUS dcerpc_bind(struct dcerpc_pipe *p,
|
|||||||
pkt.u.bind.auth_info = data_blob(NULL, 0);
|
pkt.u.bind.auth_info = data_blob(NULL, 0);
|
||||||
|
|
||||||
/* construct the NDR form of the packet */
|
/* construct the NDR form of the packet */
|
||||||
status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->auth_info);
|
status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->auth_info, p->flags);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -353,7 +402,7 @@ NTSTATUS dcerpc_auth3(struct dcerpc_pipe *p,
|
|||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
DATA_BLOB blob;
|
DATA_BLOB blob;
|
||||||
|
|
||||||
init_dcerpc_hdr(&pkt);
|
init_dcerpc_hdr(p, &pkt);
|
||||||
|
|
||||||
pkt.ptype = DCERPC_PKT_AUTH3;
|
pkt.ptype = DCERPC_PKT_AUTH3;
|
||||||
pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
|
pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
|
||||||
@ -363,7 +412,7 @@ NTSTATUS dcerpc_auth3(struct dcerpc_pipe *p,
|
|||||||
pkt.u.auth.auth_info = data_blob(NULL, 0);
|
pkt.u.auth.auth_info = data_blob(NULL, 0);
|
||||||
|
|
||||||
/* construct the NDR form of the packet */
|
/* construct the NDR form of the packet */
|
||||||
status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->auth_info);
|
status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->auth_info, p->flags);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -392,15 +441,13 @@ NTSTATUS dcerpc_bind_byuuid(struct dcerpc_pipe *p,
|
|||||||
DEBUG(2,("Invalid uuid string in dcerpc_bind_byuuid\n"));
|
DEBUG(2,("Invalid uuid string in dcerpc_bind_byuuid\n"));
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
syntax.major_version = version;
|
syntax.if_version = version;
|
||||||
syntax.minor_version = 0;
|
|
||||||
|
|
||||||
status = GUID_from_string(NDR_GUID, &transfer_syntax.uuid);
|
status = GUID_from_string(NDR_GUID, &transfer_syntax.uuid);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
transfer_syntax.major_version = NDR_GUID_VERSION;
|
transfer_syntax.if_version = NDR_GUID_VERSION;
|
||||||
transfer_syntax.minor_version = 0;
|
|
||||||
|
|
||||||
return dcerpc_bind(p, mem_ctx, &syntax, &transfer_syntax);
|
return dcerpc_bind(p, mem_ctx, &syntax, &transfer_syntax);
|
||||||
}
|
}
|
||||||
@ -420,7 +467,7 @@ NTSTATUS dcerpc_request(struct dcerpc_pipe *p,
|
|||||||
DATA_BLOB blob, payload;
|
DATA_BLOB blob, payload;
|
||||||
uint32 remaining, chunk_size;
|
uint32 remaining, chunk_size;
|
||||||
|
|
||||||
init_dcerpc_hdr(&pkt);
|
init_dcerpc_hdr(p, &pkt);
|
||||||
|
|
||||||
remaining = stub_data_in->length;
|
remaining = stub_data_in->length;
|
||||||
|
|
||||||
@ -552,6 +599,12 @@ NTSTATUS dcerpc_request(struct dcerpc_pipe *p,
|
|||||||
*stub_data_out = payload;
|
*stub_data_out = payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(pkt.drep[0] & 0x10)) {
|
||||||
|
p->flags |= DCERPC_PULL_BIGENDIAN;
|
||||||
|
} else {
|
||||||
|
p->flags &= ~DCERPC_PULL_BIGENDIAN;
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -723,6 +776,10 @@ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p,
|
|||||||
return NT_STATUS_NO_MEMORY;
|
return NT_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p->flags & DCERPC_PUSH_BIGENDIAN) {
|
||||||
|
push->flags |= LIBNDR_FLAG_BIGENDIAN;
|
||||||
|
}
|
||||||
|
|
||||||
/* push the structure into a blob */
|
/* push the structure into a blob */
|
||||||
status = ndr_push(push, NDR_IN, struct_ptr);
|
status = ndr_push(push, NDR_IN, struct_ptr);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
@ -755,6 +812,10 @@ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p,
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p->flags & DCERPC_PULL_BIGENDIAN) {
|
||||||
|
pull->flags |= LIBNDR_FLAG_BIGENDIAN;
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG(10,("rpc reply data:\n"));
|
DEBUG(10,("rpc reply data:\n"));
|
||||||
dump_data(10, pull->data, pull->data_size);
|
dump_data(10, pull->data, pull->data_size);
|
||||||
|
|
||||||
|
@ -65,6 +65,9 @@ struct dcerpc_pipe {
|
|||||||
#define DCERPC_SIGN 16
|
#define DCERPC_SIGN 16
|
||||||
#define DCERPC_SEAL 32
|
#define DCERPC_SEAL 32
|
||||||
|
|
||||||
|
#define DCERPC_PUSH_BIGENDIAN 64
|
||||||
|
#define DCERPC_PULL_BIGENDIAN 128
|
||||||
|
|
||||||
/*
|
/*
|
||||||
this is used to find pointers to calls
|
this is used to find pointers to calls
|
||||||
*/
|
*/
|
||||||
|
@ -91,7 +91,7 @@ static NTSTATUS dcerpc_raw_recv(struct dcerpc_pipe *p,
|
|||||||
|
|
||||||
/* we might have recieved a partial fragment, in which case we
|
/* we might have recieved a partial fragment, in which case we
|
||||||
need to pull the rest of it */
|
need to pull the rest of it */
|
||||||
frag_length = SVAL(payload.data, 8);
|
frag_length = dcerpc_get_frag_length(&payload);
|
||||||
if (frag_length <= payload.length) {
|
if (frag_length <= payload.length) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -197,7 +197,7 @@ NTSTATUS smb_secondary_request(struct dcerpc_pipe *p,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
frag_length = SVAL(blob->data, 8);
|
frag_length = dcerpc_get_frag_length(blob);
|
||||||
if (frag_length <= blob->length) {
|
if (frag_length <= blob->length) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ static NTSTATUS tcp_raw_recv(struct dcerpc_pipe *p,
|
|||||||
|
|
||||||
/* we might have recieved a partial fragment, in which case we
|
/* we might have recieved a partial fragment, in which case we
|
||||||
need to pull the rest of it */
|
need to pull the rest of it */
|
||||||
frag_length = SVAL(blob1.data, 8);
|
frag_length = dcerpc_get_frag_length(&blob1);
|
||||||
if (frag_length == blob1.length) {
|
if (frag_length == blob1.length) {
|
||||||
*blob = blob1;
|
*blob = blob1;
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
|
@ -59,7 +59,7 @@ NTSTATUS dcerpc_epm_map_tcp_port(const char *server,
|
|||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
struct epm_Map r;
|
struct epm_Map r;
|
||||||
struct policy_handle handle;
|
struct policy_handle handle;
|
||||||
GUID guid;
|
struct GUID guid;
|
||||||
struct epm_twr_t twr, *twr_r;
|
struct epm_twr_t twr, *twr_r;
|
||||||
|
|
||||||
if (strcasecmp(uuid, DCERPC_EPMAPPER_UUID) == 0 ||
|
if (strcasecmp(uuid, DCERPC_EPMAPPER_UUID) == 0 ||
|
||||||
@ -223,7 +223,8 @@ const struct dcerpc_interface_table *idl_iface_by_uuid(const char *uuid)
|
|||||||
*/
|
*/
|
||||||
NTSTATUS dcerpc_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
|
NTSTATUS dcerpc_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
|
||||||
struct dcerpc_packet *pkt,
|
struct dcerpc_packet *pkt,
|
||||||
struct dcerpc_auth *auth_info)
|
struct dcerpc_auth *auth_info,
|
||||||
|
unsigned flags)
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
struct ndr_push *ndr;
|
struct ndr_push *ndr;
|
||||||
@ -233,6 +234,10 @@ NTSTATUS dcerpc_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
|
|||||||
return NT_STATUS_NO_MEMORY;
|
return NT_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flags & DCERPC_PUSH_BIGENDIAN) {
|
||||||
|
ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
|
||||||
|
}
|
||||||
|
|
||||||
if (auth_info) {
|
if (auth_info) {
|
||||||
pkt->auth_length = auth_info->credentials.length;
|
pkt->auth_length = auth_info->credentials.length;
|
||||||
} else {
|
} else {
|
||||||
@ -251,7 +256,7 @@ NTSTATUS dcerpc_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
|
|||||||
*blob = ndr_push_blob(ndr);
|
*blob = ndr_push_blob(ndr);
|
||||||
|
|
||||||
/* fill in the frag length */
|
/* fill in the frag length */
|
||||||
SSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET, blob->length);
|
dcerpc_set_frag_length(blob, blob->length);
|
||||||
|
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
@ -278,7 +283,8 @@ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_
|
|||||||
} options[] = {
|
} options[] = {
|
||||||
{"sign", DCERPC_SIGN},
|
{"sign", DCERPC_SIGN},
|
||||||
{"seal", DCERPC_SEAL},
|
{"seal", DCERPC_SEAL},
|
||||||
{"validate", DCERPC_DEBUG_VALIDATE_BOTH}
|
{"validate", DCERPC_DEBUG_VALIDATE_BOTH},
|
||||||
|
{"bigendian", DCERPC_PUSH_BIGENDIAN}
|
||||||
};
|
};
|
||||||
|
|
||||||
p = strchr(s, ':');
|
p = strchr(s, ':');
|
||||||
|
@ -181,10 +181,13 @@ static NTSTATUS ipc_setpathinfo(struct request_context *req, union smb_setfilein
|
|||||||
return NT_STATUS_ACCESS_DENIED;
|
return NT_STATUS_ACCESS_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
open a file - used for MSRPC pipes
|
open a file backend - used for MSRPC pipes
|
||||||
*/
|
*/
|
||||||
static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi)
|
static NTSTATUS ipc_open_generic(struct request_context *req, const char *fname,
|
||||||
|
struct pipe_state **ps)
|
||||||
{
|
{
|
||||||
struct pipe_state *p;
|
struct pipe_state *p;
|
||||||
TALLOC_CTX *mem_ctx;
|
TALLOC_CTX *mem_ctx;
|
||||||
@ -192,12 +195,7 @@ static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi)
|
|||||||
struct dcesrv_endpoint endpoint;
|
struct dcesrv_endpoint endpoint;
|
||||||
struct ipc_private *private = req->conn->ntvfs_private;
|
struct ipc_private *private = req->conn->ntvfs_private;
|
||||||
|
|
||||||
/* for now only handle NTcreateX style opens */
|
mem_ctx = talloc_init("ipc_open '%s'", fname);
|
||||||
if (oi->generic.level != RAW_OPEN_NTCREATEX) {
|
|
||||||
return NT_STATUS_ACCESS_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
mem_ctx = talloc_init("ipc_open '%s'", oi->ntcreatex.in.fname);
|
|
||||||
if (!mem_ctx) {
|
if (!mem_ctx) {
|
||||||
return NT_STATUS_NO_MEMORY;
|
return NT_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
@ -209,7 +207,7 @@ static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi)
|
|||||||
}
|
}
|
||||||
p->mem_ctx = mem_ctx;
|
p->mem_ctx = mem_ctx;
|
||||||
|
|
||||||
p->pipe_name = talloc_strdup(mem_ctx, oi->ntcreatex.in.fname);
|
p->pipe_name = talloc_strdup(mem_ctx, fname);
|
||||||
if (!p->pipe_name) {
|
if (!p->pipe_name) {
|
||||||
talloc_destroy(mem_ctx);
|
talloc_destroy(mem_ctx);
|
||||||
return NT_STATUS_NO_MEMORY;
|
return NT_STATUS_NO_MEMORY;
|
||||||
@ -250,11 +248,79 @@ static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi)
|
|||||||
|
|
||||||
DLIST_ADD(private->pipe_list, p);
|
DLIST_ADD(private->pipe_list, p);
|
||||||
|
|
||||||
|
*ps = p;
|
||||||
|
|
||||||
|
return NT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
open a file with ntcreatex - used for MSRPC pipes
|
||||||
|
*/
|
||||||
|
static NTSTATUS ipc_open_ntcreatex(struct request_context *req, union smb_open *oi)
|
||||||
|
{
|
||||||
|
struct pipe_state *p;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
status = ipc_open_generic(req, oi->ntcreatex.in.fname, &p);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
ZERO_STRUCT(oi->ntcreatex.out);
|
ZERO_STRUCT(oi->ntcreatex.out);
|
||||||
oi->ntcreatex.out.fnum = p->fnum;
|
oi->ntcreatex.out.fnum = p->fnum;
|
||||||
oi->ntcreatex.out.ipc_state = p->ipc_state;
|
oi->ntcreatex.out.ipc_state = p->ipc_state;
|
||||||
|
|
||||||
return NT_STATUS_OK;
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
open a file with openx - used for MSRPC pipes
|
||||||
|
*/
|
||||||
|
static NTSTATUS ipc_open_openx(struct request_context *req, union smb_open *oi)
|
||||||
|
{
|
||||||
|
struct pipe_state *p;
|
||||||
|
NTSTATUS status;
|
||||||
|
const char *fname = oi->openx.in.fname;
|
||||||
|
|
||||||
|
if (strncasecmp(fname, "PIPE\\", 5) != 0) {
|
||||||
|
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
fname += 4;
|
||||||
|
|
||||||
|
status = ipc_open_generic(req, fname, &p);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZERO_STRUCT(oi->openx.out);
|
||||||
|
oi->openx.out.fnum = p->fnum;
|
||||||
|
oi->openx.out.ftype = 2;
|
||||||
|
oi->openx.out.devstate = p->ipc_state;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
open a file - used for MSRPC pipes
|
||||||
|
*/
|
||||||
|
static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
switch (oi->generic.level) {
|
||||||
|
case RAW_OPEN_NTCREATEX:
|
||||||
|
status = ipc_open_ntcreatex(req, oi);
|
||||||
|
break;
|
||||||
|
case RAW_OPEN_OPENX:
|
||||||
|
status = ipc_open_openx(req, oi);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
status = NT_STATUS_NOT_SUPPORTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -141,25 +141,44 @@ BOOL secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL secrets_store_domain_guid(const char *domain, GUID *guid)
|
BOOL secrets_store_domain_guid(const char *domain, struct GUID *guid)
|
||||||
{
|
{
|
||||||
|
const char *s;
|
||||||
fstring key;
|
fstring key;
|
||||||
|
TALLOC_CTX *mem_ctx;
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
|
mem_ctx = talloc_init("secrets_store_domain_guid");
|
||||||
strupper(key);
|
if (!mem_ctx) {
|
||||||
return secrets_store(key, guid, sizeof(GUID));
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = GUID_string(mem_ctx, guid);
|
||||||
|
if (!s) {
|
||||||
|
talloc_destroy(mem_ctx);
|
||||||
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL secrets_fetch_domain_guid(const char *domain, GUID *guid)
|
|
||||||
{
|
|
||||||
GUID *dyn_guid;
|
|
||||||
fstring key;
|
|
||||||
size_t size;
|
|
||||||
GUID new_guid;
|
|
||||||
|
|
||||||
slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
|
slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
|
||||||
strupper(key);
|
strupper(key);
|
||||||
dyn_guid = (GUID *)secrets_fetch(key, &size);
|
ret = secrets_store(key, s, strlen(s)+1);
|
||||||
|
|
||||||
|
talloc_destroy(mem_ctx);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
|
||||||
|
{
|
||||||
|
char *dyn_guid;
|
||||||
|
fstring key;
|
||||||
|
size_t size;
|
||||||
|
struct GUID new_guid;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
|
||||||
|
strupper(key);
|
||||||
|
dyn_guid = secrets_fetch(key, &size);
|
||||||
|
|
||||||
DEBUG(6,("key is %s, size is %d\n", key, (int)size));
|
DEBUG(6,("key is %s, size is %d\n", key, (int)size));
|
||||||
|
|
||||||
@ -167,19 +186,18 @@ BOOL secrets_fetch_domain_guid(const char *domain, GUID *guid)
|
|||||||
uuid_generate_random(&new_guid);
|
uuid_generate_random(&new_guid);
|
||||||
if (!secrets_store_domain_guid(domain, &new_guid))
|
if (!secrets_store_domain_guid(domain, &new_guid))
|
||||||
return False;
|
return False;
|
||||||
dyn_guid = (GUID *)secrets_fetch(key, &size);
|
dyn_guid = secrets_fetch(key, &size);
|
||||||
if (dyn_guid == NULL)
|
if (dyn_guid == NULL)
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size != sizeof(GUID))
|
status = GUID_from_string(dyn_guid, guid);
|
||||||
{
|
|
||||||
SAFE_FREE(dyn_guid);
|
SAFE_FREE(dyn_guid);
|
||||||
|
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
*guid = *dyn_guid;
|
|
||||||
SAFE_FREE(dyn_guid);
|
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32 fault_code)
|
|||||||
return NT_STATUS_NO_MEMORY;
|
return NT_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL);
|
status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL, 0);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -266,7 +266,7 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32 reason)
|
|||||||
return NT_STATUS_NO_MEMORY;
|
return NT_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL);
|
status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL, 0);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -296,13 +296,13 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
|
|||||||
return dcesrv_bind_nak(call, 0);
|
return dcesrv_bind_nak(call, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if_version = call->pkt.u.bind.ctx_list[0].abstract_syntax.major_version;
|
if_version = call->pkt.u.bind.ctx_list[0].abstract_syntax.if_version;
|
||||||
uuid = GUID_string(call->mem_ctx, &call->pkt.u.bind.ctx_list[0].abstract_syntax.uuid);
|
uuid = GUID_string(call->mem_ctx, &call->pkt.u.bind.ctx_list[0].abstract_syntax.uuid);
|
||||||
if (!uuid) {
|
if (!uuid) {
|
||||||
return dcesrv_bind_nak(call, 0);
|
return dcesrv_bind_nak(call, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer_syntax_version = call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].major_version;
|
transfer_syntax_version = call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].if_version;
|
||||||
transfer_syntax = GUID_string(call->mem_ctx,
|
transfer_syntax = GUID_string(call->mem_ctx,
|
||||||
&call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].uuid);
|
&call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].uuid);
|
||||||
if (!transfer_syntax ||
|
if (!transfer_syntax ||
|
||||||
@ -356,8 +356,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
|
|||||||
pkt.u.bind_ack.ctx_list[0].result = result;
|
pkt.u.bind_ack.ctx_list[0].result = result;
|
||||||
pkt.u.bind_ack.ctx_list[0].reason = reason;
|
pkt.u.bind_ack.ctx_list[0].reason = reason;
|
||||||
GUID_from_string(NDR_GUID, &pkt.u.bind_ack.ctx_list[0].syntax.uuid);
|
GUID_from_string(NDR_GUID, &pkt.u.bind_ack.ctx_list[0].syntax.uuid);
|
||||||
pkt.u.bind_ack.ctx_list[0].syntax.major_version = NDR_GUID_VERSION;
|
pkt.u.bind_ack.ctx_list[0].syntax.if_version = NDR_GUID_VERSION;
|
||||||
pkt.u.bind_ack.ctx_list[0].syntax.minor_version = 0;
|
|
||||||
pkt.u.bind_ack.auth_info = data_blob(NULL, 0);
|
pkt.u.bind_ack.auth_info = data_blob(NULL, 0);
|
||||||
|
|
||||||
if (!dcesrv_auth_bind_ack(call, &pkt)) {
|
if (!dcesrv_auth_bind_ack(call, &pkt)) {
|
||||||
@ -370,7 +369,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
|
|||||||
}
|
}
|
||||||
|
|
||||||
status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt,
|
status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt,
|
||||||
call->dce->auth_state.auth_info);
|
call->dce->auth_state.auth_info, 0);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -232,7 +232,7 @@ BOOL dcesrv_auth_response(struct dcesrv_call_state *call,
|
|||||||
|
|
||||||
/* non-signed packets are simple */
|
/* non-signed packets are simple */
|
||||||
if (!dce->auth_state.auth_info || !dce->auth_state.ntlmssp_state) {
|
if (!dce->auth_state.auth_info || !dce->auth_state.ntlmssp_state) {
|
||||||
status = dcerpc_push_auth(blob, call->mem_ctx, pkt, NULL);
|
status = dcerpc_push_auth(blob, call->mem_ctx, pkt, NULL, 0);
|
||||||
return NT_STATUS_IS_OK(status);
|
return NT_STATUS_IS_OK(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ enum handle_types {HTYPE_LOOKUP};
|
|||||||
/*
|
/*
|
||||||
simple routine to compare a GUID string to a GUID structure
|
simple routine to compare a GUID string to a GUID structure
|
||||||
*/
|
*/
|
||||||
static int guid_cmp(TALLOC_CTX *mem_ctx, const GUID *guid, const char *uuid_str)
|
static int guid_cmp(TALLOC_CTX *mem_ctx, const struct GUID *guid, const char *uuid_str)
|
||||||
{
|
{
|
||||||
const char *s = GUID_string(mem_ctx, guid);
|
const char *s = GUID_string(mem_ctx, guid);
|
||||||
if (!s || strcasecmp(s, uuid_str)) {
|
if (!s || strcasecmp(s, uuid_str)) {
|
||||||
|
@ -202,6 +202,7 @@ static NTSTATUS trans2_qfsinfo(struct request_context *req, struct smb_trans2 *t
|
|||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
uint16 level;
|
uint16 level;
|
||||||
uint_t i;
|
uint_t i;
|
||||||
|
DATA_BLOB guid_blob;
|
||||||
|
|
||||||
/* make sure we got enough parameters */
|
/* make sure we got enough parameters */
|
||||||
if (trans->in.params.length != 2) {
|
if (trans->in.params.length != 2) {
|
||||||
@ -369,7 +370,15 @@ static NTSTATUS trans2_qfsinfo(struct request_context *req, struct smb_trans2 *t
|
|||||||
|
|
||||||
trans2_setup_reply(req, trans, 0, 64, 0);
|
trans2_setup_reply(req, trans, 0, 64, 0);
|
||||||
|
|
||||||
memcpy(trans->out.data.data, fsinfo.objectid_information.out.guid.info, GUID_SIZE);
|
status = ndr_push_struct_blob(&guid_blob, req->mem_ctx,
|
||||||
|
&fsinfo.objectid_information.out.guid,
|
||||||
|
(ndr_push_flags_fn_t)ndr_push_GUID);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(trans->out.data.data, guid_blob.data, GUID_SIZE);
|
||||||
|
|
||||||
for (i=0;i<6;i++) {
|
for (i=0;i<6;i++) {
|
||||||
SBVAL(trans->out.data.data, 16 + 8*i, fsinfo.objectid_information.out.unknown[i]);
|
SBVAL(trans->out.data.data, 16 + 8*i, fsinfo.objectid_information.out.unknown[i]);
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ static BOOL test_Map(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
|||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
struct epm_Map r;
|
struct epm_Map r;
|
||||||
GUID uuid;
|
struct GUID uuid;
|
||||||
const char *uuid_str;
|
const char *uuid_str;
|
||||||
struct policy_handle handle;
|
struct policy_handle handle;
|
||||||
int i;
|
int i;
|
||||||
|
@ -55,10 +55,9 @@ static BOOL test_inq_if_ids(struct dcerpc_pipe *p,
|
|||||||
|
|
||||||
uuid = GUID_string(mem_ctx, &id->uuid);
|
uuid = GUID_string(mem_ctx, &id->uuid);
|
||||||
|
|
||||||
printf("\tuuid %s version 0x%04x:0x%04x '%s'\n",
|
printf("\tuuid %s version 0x%08x '%s'\n",
|
||||||
uuid,
|
uuid,
|
||||||
id->major_version, id->minor_version,
|
id->if_version, idl_pipe_name(uuid, id->if_version));
|
||||||
idl_pipe_name(uuid, id->major_version));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return True;
|
return True;
|
||||||
|
@ -39,7 +39,7 @@ static BOOL test_num_calls(const struct dcerpc_interface_table *iface,
|
|||||||
uuid = GUID_string(mem_ctx, &id->uuid);
|
uuid = GUID_string(mem_ctx, &id->uuid);
|
||||||
|
|
||||||
status = torture_rpc_connection(&p, iface->name,
|
status = torture_rpc_connection(&p, iface->name,
|
||||||
uuid, id->major_version);
|
uuid, id->if_version);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
printf("Failed to connect to '%s' on '%s' - %s\n",
|
printf("Failed to connect to '%s' on '%s' - %s\n",
|
||||||
uuid, iface->name, nt_errstr(status));
|
uuid, iface->name, nt_errstr(status));
|
||||||
@ -69,7 +69,7 @@ static BOOL test_num_calls(const struct dcerpc_interface_table *iface,
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("\t%d calls available\n", i);
|
printf("\t%d calls available\n", i);
|
||||||
idl_calls = idl_num_calls(uuid, id->major_version);
|
idl_calls = idl_num_calls(uuid, id->if_version);
|
||||||
if (idl_calls == -1) {
|
if (idl_calls == -1) {
|
||||||
printf("\tinterface not known in local IDL\n");
|
printf("\tinterface not known in local IDL\n");
|
||||||
} else if (i != idl_calls) {
|
} else if (i != idl_calls) {
|
||||||
@ -117,10 +117,9 @@ static BOOL test_inq_if_ids(struct dcerpc_pipe *p,
|
|||||||
|
|
||||||
uuid = GUID_string(mem_ctx, &id->uuid),
|
uuid = GUID_string(mem_ctx, &id->uuid),
|
||||||
|
|
||||||
printf("\n\tuuid %s version 0x%04x:0x%04x '%s'\n",
|
printf("\n\tuuid %s version 0x%08x '%s'\n",
|
||||||
uuid,
|
uuid,
|
||||||
id->major_version, id->minor_version,
|
id->if_version, idl_pipe_name(uuid, id->if_version));
|
||||||
idl_pipe_name(uuid, id->major_version));
|
|
||||||
test_num_calls(iface, mem_ctx, id);
|
test_num_calls(iface, mem_ctx, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user