From 54abd2aa66069e6baf7769c496f46d9dba18db39 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 30 Sep 2005 17:13:37 +0000 Subject: r10656: BIG merge from trunk. Features not copied over * \PIPE\unixinfo * winbindd's {group,alias}membership new functions * winbindd's lookupsids() functionality * swat (trunk changes to be reverted as per discussion with Deryck) (This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3) --- source3/rpc_parse/parse_prs.c | 146 +++++++++++++++++++++++------------------- 1 file changed, 80 insertions(+), 66 deletions(-) (limited to 'source3/rpc_parse/parse_prs.c') diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c index 709a5d39af..d174bad444 100644 --- a/source3/rpc_parse/parse_prs.c +++ b/source3/rpc_parse/parse_prs.c @@ -34,7 +34,6 @@ void prs_dump(char *name, int v, prs_struct *ps) prs_dump_region(name, v, ps, ps->data_offset, ps->buffer_size); } - /** * Dump from the start of the prs to the current location. **/ @@ -43,7 +42,6 @@ void prs_dump_before(char *name, int v, prs_struct *ps) prs_dump_region(name, v, ps, 0, ps->data_offset); } - /** * Dump everything from the start of the prs up to the current location. **/ @@ -52,6 +50,7 @@ void prs_dump_region(char *name, int v, prs_struct *ps, { int fd, i; pstring fname; + ssize_t sz; if (DEBUGLEVEL < 50) return; for (i=1;i<100;i++) { if (v != -1) { @@ -63,26 +62,28 @@ void prs_dump_region(char *name, int v, prs_struct *ps, if (fd != -1 || errno != EEXIST) break; } if (fd != -1) { - write(fd, ps->data_p + from_off, to_off - from_off); - close(fd); - DEBUG(0,("created %s\n", fname)); + sz = write(fd, ps->data_p + from_off, to_off - from_off); + i = close(fd); + if ( (sz != to_off-from_off) || (i != 0) ) { + DEBUG(0,("Error writing/closing %s: %ld!=%ld %d\n", fname, (unsigned long)sz, (unsigned long)to_off-from_off, i )); + } else { + DEBUG(0,("created %s\n", fname)); + } } } - - /******************************************************************* - debug output for parsing info. + Debug output for parsing info - XXXX side-effect of this function is to increase the debug depth XXXX + XXXX side-effect of this function is to increase the debug depth XXXX. + +********************************************************************/ - ********************************************************************/ void prs_debug(prs_struct *ps, int depth, const char *desc, const char *fn_name) { DEBUG(5+depth, ("%s%06x %s %s\n", tab_depth(depth), ps->data_offset, fn_name, desc)); } - /** * Initialise an expandable parse structure. * @@ -91,6 +92,7 @@ void prs_debug(prs_struct *ps, int depth, const char *desc, const char *fn_name) * * @return False if allocation fails, otherwise True. **/ + BOOL prs_init(prs_struct *ps, uint32 size, TALLOC_CTX *ctx, BOOL io) { ZERO_STRUCTP(ps); @@ -111,6 +113,9 @@ BOOL prs_init(prs_struct *ps, uint32 size, TALLOC_CTX *ctx, BOOL io) } memset(ps->data_p, '\0', (size_t)size); ps->is_dynamic = True; /* We own this memory. */ + } else if (MARSHALLING(ps)) { + /* If size is zero and we're marshalling we should allocate memory on demand. */ + ps->is_dynamic = True; } return True; @@ -254,7 +259,7 @@ BOOL prs_grow(prs_struct *ps, uint32 extra_space) * is greater. */ - new_size = MAX(MAX_PDU_FRAG_LEN,extra_space); + new_size = MAX(RPC_MAX_PDU_FRAG_LEN,extra_space); if((new_data = SMB_MALLOC(new_size)) == NULL) { DEBUG(0,("prs_grow: Malloc failure for size %u.\n", (unsigned int)new_size)); @@ -398,7 +403,7 @@ BOOL prs_append_some_prs_data(prs_struct *dst, prs_struct *src, int32 start, uin Append the data from a buffer into a parse_struct. ********************************************************************/ -BOOL prs_copy_data_in(prs_struct *dst, char *src, uint32 len) +BOOL prs_copy_data_in(prs_struct *dst, const char *src, uint32 len) { if (len == 0) return True; @@ -564,6 +569,15 @@ void prs_force_dynamic(prs_struct *ps) ps->is_dynamic=True; } +/******************************************************************* + Associate a session key with a parse struct. + ********************************************************************/ + +void prs_set_session_key(prs_struct *ps, const char sess_key[16]) +{ + ps->sess_key = sess_key; +} + /******************************************************************* Stream a uint8. ********************************************************************/ @@ -596,9 +610,9 @@ BOOL prs_pointer( const char *name, prs_struct *ps, int depth, { uint32 data_p; - /* caputure the pointer value to stream */ + /* output f000baaa to stream if the pointer is non-zero. */ - data_p = (uint32) *data; + data_p = *data ? 0xf000baaa : 0; if ( !prs_uint32("ptr", ps, depth, &data_p )) return False; @@ -1387,7 +1401,7 @@ int tdb_prs_fetch(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps, TALLOC_CTX *me hash a stream. ********************************************************************/ -BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16], int len) +BOOL prs_hash1(prs_struct *ps, uint32 offset, int len) { char *q; @@ -1396,10 +1410,10 @@ BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16], int len) #ifdef DEBUG_PASSWORD DEBUG(100, ("prs_hash1\n")); - dump_data(100, sess_key, 16); + dump_data(100, ps->sess_key, 16); dump_data(100, q, len); #endif - SamOEMhash((uchar *) q, sess_key, len); + SamOEMhash((uchar *) q, ps->sess_key, len); #ifdef DEBUG_PASSWORD dump_data(100, q, len); @@ -1413,9 +1427,9 @@ BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16], int len) MD5 it with the session key. ********************************************************************/ -static void netsec_digest(struct netsec_auth_struct *a, - int auth_flags, - RPC_AUTH_NETSEC_CHK * verf, +static void schannel_digest(struct schannel_auth_struct *a, + enum pipe_auth_level auth_level, + RPC_AUTH_SCHANNEL_CHK * verf, char *data, size_t data_len, uchar digest_final[16]) { @@ -1429,7 +1443,7 @@ static void netsec_digest(struct netsec_auth_struct *a, out of order */ MD5Update(&ctx3, zeros, sizeof(zeros)); MD5Update(&ctx3, verf->sig, sizeof(verf->sig)); - if (auth_flags & AUTH_PIPE_SEAL) { + if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) { MD5Update(&ctx3, verf->confounder, sizeof(verf->confounder)); } MD5Update(&ctx3, (const unsigned char *)data, data_len); @@ -1445,8 +1459,8 @@ static void netsec_digest(struct netsec_auth_struct *a, Calculate the key with which to encode the data payload ********************************************************************/ -static void netsec_get_sealing_key(struct netsec_auth_struct *a, - RPC_AUTH_NETSEC_CHK *verf, +static void schannel_get_sealing_key(struct schannel_auth_struct *a, + RPC_AUTH_SCHANNEL_CHK *verf, uchar sealing_key[16]) { static uchar zeros[4]; @@ -1473,8 +1487,8 @@ static void netsec_get_sealing_key(struct netsec_auth_struct *a, Encode or Decode the sequence number (which is symmetric) ********************************************************************/ -static void netsec_deal_with_seq_num(struct netsec_auth_struct *a, - RPC_AUTH_NETSEC_CHK *verf) +static void schannel_deal_with_seq_num(struct schannel_auth_struct *a, + RPC_AUTH_SCHANNEL_CHK *verf) { static uchar zeros[4]; uchar sequence_key[16]; @@ -1493,10 +1507,10 @@ static void netsec_deal_with_seq_num(struct netsec_auth_struct *a, } /******************************************************************* -creates an RPC_AUTH_NETSEC_CHK structure. +creates an RPC_AUTH_SCHANNEL_CHK structure. ********************************************************************/ -static BOOL init_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk, +static BOOL init_rpc_auth_schannel_chk(RPC_AUTH_SCHANNEL_CHK * chk, const uchar sig[8], const uchar packet_digest[8], const uchar seq_num[8], const uchar confounder[8]) @@ -1513,15 +1527,15 @@ static BOOL init_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk, } /******************************************************************* - Encode a blob of data using the netsec (schannel) alogrithm, also produceing + Encode a blob of data using the schannel alogrithm, also produceing a checksum over the original data. We currently only support signing and sealing togeather - the signing-only code is close, but not quite compatible with what MS does. ********************************************************************/ -void netsec_encode(struct netsec_auth_struct *a, int auth_flags, - enum netsec_direction direction, - RPC_AUTH_NETSEC_CHK * verf, +void schannel_encode(struct schannel_auth_struct *a, enum pipe_auth_level auth_level, + enum schannel_direction direction, + RPC_AUTH_SCHANNEL_CHK * verf, char *data, size_t data_len) { uchar digest_final[16]; @@ -1529,16 +1543,16 @@ void netsec_encode(struct netsec_auth_struct *a, int auth_flags, uchar seq_num[8]; static const uchar nullbytes[8]; - static const uchar netsec_seal_sig[8] = NETSEC_SEAL_SIGNATURE; - static const uchar netsec_sign_sig[8] = NETSEC_SIGN_SIGNATURE; - const uchar *netsec_sig = NULL; + static const uchar schannel_seal_sig[8] = SCHANNEL_SEAL_SIGNATURE; + static const uchar schannel_sign_sig[8] = SCHANNEL_SIGN_SIGNATURE; + const uchar *schannel_sig = NULL; - DEBUG(10,("SCHANNEL: netsec_encode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len)); + DEBUG(10,("SCHANNEL: schannel_encode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len)); - if (auth_flags & AUTH_PIPE_SEAL) { - netsec_sig = netsec_seal_sig; - } else if (auth_flags & AUTH_PIPE_SIGN) { - netsec_sig = netsec_sign_sig; + if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) { + schannel_sig = schannel_seal_sig; + } else { + schannel_sig = schannel_sign_sig; } /* fill the 'confounder' with random data */ @@ -1559,18 +1573,18 @@ void netsec_encode(struct netsec_auth_struct *a, int auth_flags, dump_data_pw("verf->seq_num:\n", seq_num, sizeof(verf->seq_num)); - init_rpc_auth_netsec_chk(verf, netsec_sig, nullbytes, + init_rpc_auth_schannel_chk(verf, schannel_sig, nullbytes, seq_num, confounder); /* produce a digest of the packet to prove it's legit (before we seal it) */ - netsec_digest(a, auth_flags, verf, data, data_len, digest_final); + schannel_digest(a, auth_level, verf, data, data_len, digest_final); memcpy(verf->packet_digest, digest_final, sizeof(verf->packet_digest)); - if (auth_flags & AUTH_PIPE_SEAL) { + if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) { uchar sealing_key[16]; /* get the key to encode the data with */ - netsec_get_sealing_key(a, verf, sealing_key); + schannel_get_sealing_key(a, verf, sealing_key); /* encode the verification data */ dump_data_pw("verf->confounder:\n", verf->confounder, sizeof(verf->confounder)); @@ -1587,35 +1601,35 @@ void netsec_encode(struct netsec_auth_struct *a, int auth_flags, /* encode the sequence number (key based on packet digest) */ /* needs to be done after the sealing, as the original version is used in the sealing stuff... */ - netsec_deal_with_seq_num(a, verf); + schannel_deal_with_seq_num(a, verf); return; } /******************************************************************* - Decode a blob of data using the netsec (schannel) alogrithm, also verifiying + Decode a blob of data using the schannel alogrithm, also verifiying a checksum over the original data. We currently can verify signed messages, as well as decode sealed messages ********************************************************************/ -BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags, - enum netsec_direction direction, - RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len) +BOOL schannel_decode(struct schannel_auth_struct *a, enum pipe_auth_level auth_level, + enum schannel_direction direction, + RPC_AUTH_SCHANNEL_CHK * verf, char *data, size_t data_len) { uchar digest_final[16]; - static const uchar netsec_seal_sig[8] = NETSEC_SEAL_SIGNATURE; - static const uchar netsec_sign_sig[8] = NETSEC_SIGN_SIGNATURE; - const uchar *netsec_sig = NULL; + static const uchar schannel_seal_sig[8] = SCHANNEL_SEAL_SIGNATURE; + static const uchar schannel_sign_sig[8] = SCHANNEL_SIGN_SIGNATURE; + const uchar *schannel_sig = NULL; uchar seq_num[8]; - DEBUG(10,("SCHANNEL: netsec_encode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len)); + DEBUG(10,("SCHANNEL: schannel_decode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len)); - if (auth_flags & AUTH_PIPE_SEAL) { - netsec_sig = netsec_seal_sig; - } else if (auth_flags & AUTH_PIPE_SIGN) { - netsec_sig = netsec_sign_sig; + if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) { + schannel_sig = schannel_seal_sig; + } else { + schannel_sig = schannel_sign_sig; } /* Create the expected sequence number for comparison */ @@ -1630,7 +1644,7 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags, break; } - DEBUG(10,("SCHANNEL: netsec_decode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len)); + DEBUG(10,("SCHANNEL: schannel_decode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len)); dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key)); dump_data_pw("seq_num:\n", seq_num, sizeof(seq_num)); @@ -1638,7 +1652,7 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags, /* extract the sequence number (key based on supplied packet digest) */ /* needs to be done before the sealing, as the original version is used in the sealing stuff... */ - netsec_deal_with_seq_num(a, verf); + schannel_deal_with_seq_num(a, verf); if (memcmp(verf->seq_num, seq_num, sizeof(seq_num))) { /* don't even bother with the below if the sequence number is out */ @@ -1646,7 +1660,7 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags, digest, as supplied by the client. We check that it's a valid checksum after the decode, below */ - DEBUG(2, ("netsec_decode: FAILED: packet sequence number:\n")); + DEBUG(2, ("schannel_decode: FAILED: packet sequence number:\n")); dump_data(2, (const char*)verf->seq_num, sizeof(verf->seq_num)); DEBUG(2, ("should be:\n")); dump_data(2, (const char*)seq_num, sizeof(seq_num)); @@ -1654,20 +1668,20 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags, return False; } - if (memcmp(verf->sig, netsec_sig, sizeof(verf->sig))) { + if (memcmp(verf->sig, schannel_sig, sizeof(verf->sig))) { /* Validate that the other end sent the expected header */ - DEBUG(2, ("netsec_decode: FAILED: packet header:\n")); + DEBUG(2, ("schannel_decode: FAILED: packet header:\n")); dump_data(2, (const char*)verf->sig, sizeof(verf->sig)); DEBUG(2, ("should be:\n")); - dump_data(2, (const char*)netsec_sig, sizeof(netsec_sig)); + dump_data(2, (const char*)schannel_sig, sizeof(schannel_sig)); return False; } - if (auth_flags & AUTH_PIPE_SEAL) { + if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) { uchar sealing_key[16]; /* get the key to extract the data with */ - netsec_get_sealing_key(a, verf, sealing_key); + schannel_get_sealing_key(a, verf, sealing_key); /* extract the verification data */ dump_data_pw("verf->confounder:\n", verf->confounder, @@ -1684,7 +1698,7 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags, } /* digest includes 'data' after unsealing */ - netsec_digest(a, auth_flags, verf, data, data_len, digest_final); + schannel_digest(a, auth_level, verf, data, data_len, digest_final); dump_data_pw("Calculated digest:\n", digest_final, sizeof(digest_final)); -- cgit