From 297d5ef46ccba99596610c4c6a09399af665f2cf Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 4 Oct 1997 16:10:21 +0000 Subject: packet parsing routines. for use in SMB and Mailslots --- source/smbparse.c | 385 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 385 insertions(+) create mode 100644 source/smbparse.c diff --git a/source/smbparse.c b/source/smbparse.c new file mode 100644 index 00000000000..bff1a1453a4 --- /dev/null +++ b/source/smbparse.c @@ -0,0 +1,385 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + Samba utility functions + Copyright (C) Luke Leighton 1996 - 1997 + + 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. +*/ + +#include "includes.h" + +extern int DEBUGLEVEL; + + +/******************************************************************* +reads or writes an NTTIME structure. +********************************************************************/ +char* smb_io_time(BOOL io, NTTIME *nttime, char *q, char *base, int align) +{ + if (nttime == NULL) return NULL; + + q = align_offset(q, base, align); + + RW_IVAL(io, q, nttime->low , 0); q += 4; /* low part */ + RW_IVAL(io, q, nttime->high, 0); q += 4; /* high part */ + + return q; +} + +/******************************************************************* +reads or writes a DOM_SID structure. +********************************************************************/ +char* smb_io_sid(BOOL io, DOM_SID *sid, char *q, char *base, int align) +{ + int i; + + if (sid == NULL) return NULL; + + q = align_offset(q, base, align); + + RW_CVAL(io, q, sid->sid_no, 0); q++; + RW_CVAL(io, q, sid->num_auths, 0); q++; + + for (i = 0; i < 6; i++) + { + RW_CVAL(io, q, sid->id_auth[i], 0); q++; + } + + /* oops! XXXX should really issue a warning here... */ + if (sid->num_auths > MAXSUBAUTHS) sid->num_auths = MAXSUBAUTHS; + + RW_PSVAL(io, q, sid->sub_auths, sid->num_auths); q += sid->num_auths * 2; + + return q; +} + +/******************************************************************* +reads or writes a UNIHDR structure. +********************************************************************/ +char* smb_io_unihdr(BOOL io, UNIHDR *hdr, char *q, char *base, int align) +{ + if (hdr == NULL) return NULL; + + /* should be value 4, so enforce it. */ + hdr->undoc = 4; + + q = align_offset(q, base, align); + + RW_IVAL(io, q, hdr->uni_max_len, 0); q += 4; + RW_IVAL(io, q, hdr->uni_str_len, 0); q += 4; + RW_IVAL(io, q, hdr->undoc , 0); q += 4; + + return q; +} + +/******************************************************************* +reads or writes a UNIHDR2 structure. +********************************************************************/ +char* smb_io_unihdr2(BOOL io, UNIHDR2 *hdr2, char *q, char *base, int align) +{ + if (hdr2 == NULL) return NULL; + + q = align_offset(q, base, align); + + q = smb_io_unihdr(io, &(hdr2->unihdr), q, base, align); + RW_IVAL(io, q, hdr2->undoc_buffer, 0); q += 4; + + return q; +} + +/******************************************************************* +reads or writes a UNISTR structure. +XXXX NOTE: UNISTR structures NEED to be null-terminated. +********************************************************************/ +char* smb_io_unistr(BOOL io, UNISTR *uni, char *q, char *base, int align) +{ + if (uni == NULL) return NULL; + + q = align_offset(q, base, align); + + if (io) + { + /* io True indicates read _from_ the SMB buffer into the string */ + q += 2 * unistrcpy((char*)uni->buffer, q); + } + else + { + /* io True indicates copy _from_ the string into SMB buffer */ + q += 2 * unistrcpy(q, (char*)uni->buffer); + } + return q; +} + +/******************************************************************* +reads or writes a UNISTR2 structure. +XXXX NOTE: UNISTR2 structures need NOT be null-terminated. + the uni_str_len member tells you how long the string is; + the uni_max_len member tells you how large the buffer is. +********************************************************************/ +char* smb_io_unistr2(BOOL io, UNISTR2 *uni2, char *q, char *base, int align) +{ + if (uni2 == NULL) return NULL; + + q = align_offset(q, base, align); + + /* should be value 0, so enforce it. */ + uni2->undoc = 0; + + RW_IVAL(io, q, uni2->uni_max_len, 0); q += 4; + RW_IVAL(io, q, uni2->undoc , 0); q += 4; + RW_IVAL(io, q, uni2->uni_str_len, 0); q += 4; + + /* oops! XXXX maybe issue a warning that this is happening... */ + if (uni2->uni_max_len > MAX_UNISTRLEN) uni2->uni_max_len = MAX_UNISTRLEN; + if (uni2->uni_str_len > MAX_UNISTRLEN) uni2->uni_str_len = MAX_UNISTRLEN; + + /* buffer advanced by indicated length of string + NOT by searching for null-termination */ + RW_PSVAL(io, q, uni2->buffer, uni2->uni_max_len); q += uni2->uni_max_len * 2; + + return q; +} + +/******************************************************************* +reads or writes a DOM_SID2 structure. +********************************************************************/ +char* smb_io_dom_sid2(BOOL io, DOM_SID2 *sid2, char *q, char *base, int align) +{ + if (sid2 == NULL) return NULL; + + q = align_offset(q, base, align); + + /* should be value 5, so enforce it */ + sid2->type = 5; + + /* should be value 0, so enforce it */ + sid2->undoc = 0; + + RW_IVAL(io, q, sid2->type , 0); q += 4; + RW_IVAL(io, q, sid2->undoc, 0); q += 4; + + q = smb_io_unihdr2(io, &(sid2->hdr), q, base, align); + q = smb_io_unistr (io, &(sid2->str), q, base, align); + + return q; +} + +/******************************************************************* +reads or writes a DOM_RID2 structure. +********************************************************************/ +char* smb_io_dom_rid2(BOOL io, DOM_RID2 *rid2, char *q, char *base, int align) +{ + if (rid2 == NULL) return NULL; + + q = align_offset(q, base, align); + + /* should be value 5, so enforce it */ + rid2->type = 5; + + /* should be value 5, so enforce it */ + rid2->undoc = 5; + + RW_IVAL(io, q, rid2->type, 0); q += 4; + RW_IVAL(io, q, rid2->undoc , 0); q += 4; + RW_IVAL(io, q, rid2->rid , 0); q += 4; + RW_IVAL(io, q, rid2->rid_idx , 0); q += 4; + + return q; +} + +/******************************************************************* +reads or writes a DOM_LOG_INFO structure. +********************************************************************/ +char* smb_io_log_info(BOOL io, DOM_LOG_INFO *log, char *q, char *base, int align) +{ + if (log == NULL) return NULL; + + q = align_offset(q, base, align); + + RW_IVAL(io, q, log->undoc_buffer, 0); q += 4; + + q = smb_io_unistr2(io, &(log->uni_logon_srv), q, base, align); + q = smb_io_unistr2(io, &(log->uni_acct_name), q, base, align); + + RW_SVAL(io, q, log->sec_chan, 0); q += 2; + + /* XXXX no alignment required between sec_chan and uni_comp_name */ + q = smb_io_unistr2(io, &(log->uni_comp_name), q, base, 0); + + return q; +} + +/******************************************************************* +reads or writes a DOM_CRED structure. +********************************************************************/ +char* smb_io_cred(BOOL io, DOM_CRED *cred, char *q, char *base, int align) +{ + if (cred == NULL) return NULL; + + q = align_offset(q, base, align); + + RW_PCVAL(io, q, cred->data, 8); q += 8; + RW_IVAL (io, q, cred->timestamp, 0); q += 4; + + return q; +} + +/******************************************************************* +reads or writes a DOM_CLNT_INFO structure. +********************************************************************/ +char* smb_io_clnt_info(BOOL io, DOM_CLNT_INFO *clnt, char *q, char *base, int align) +{ + if (clnt == NULL) return NULL; + + q = align_offset(q, base, align); + + q = smb_io_log_info(io, &(clnt->login), q, base, align); + q = smb_io_cred (io, &(clnt->cred ), q, base, align); + + return q; +} + +/******************************************************************* +reads or writes a DOM_LOGON_ID structure. +********************************************************************/ +char* smb_io_logon_id(BOOL io, DOM_LOGON_ID *log, char *q, char *base, int align) +{ + if (log == NULL) return NULL; + + q = align_offset(q, base, align); + + RW_IVAL(io, q, log->low , 0); q += 4; + RW_IVAL(io, q, log->high, 0); q += 4; + + return q; +} + +/******************************************************************* +reads or writes an RC4_OWF structure. +********************************************************************/ +char* smb_io_rc4_owf(BOOL io, RC4_OWF *hash, char *q, char *base, int align) +{ + if (hash == NULL) return NULL; + + q = align_offset(q, base, align); + + RW_PCVAL(io, q, hash->data, 16); q += 16; + + return q; +} + +/******************************************************************* +reads or writes an DOM_ID_INFO_1 structure. +********************************************************************/ +char* smb_io_id_info1(BOOL io, DOM_ID_INFO_1 *id, char *q, char *base, int align) +{ + if (id == NULL) return NULL; + + q = align_offset(q, base, align); + + q = smb_io_unihdr(io, &(id->hdr_domain_name ), q, base, align); + + RW_IVAL(io, q, id->param, 0); q += 4; + q = smb_io_logon_id(io, &(id->logon_id), q, base, align); + + q = smb_io_unihdr(io, &(id->hdr_user_name ), q, base, align); + q = smb_io_unihdr(io, &(id->hdr_workgroup_name), q, base, align); + + q = smb_io_rc4_owf(io, &(id->rc4_lm_owf), q, base, align); + q = smb_io_rc4_owf(io, &(id->rc4_nt_owf), q, base, align); + + q = smb_io_unistr2(io, &(id->uni_domain_name ), q, base, align); + q = smb_io_unistr2(io, &(id->uni_user_name ), q, base, align); + q = smb_io_unistr2(io, &(id->uni_workgroup_name), q, base, align); + + return q; +} + +/******************************************************************* +reads or writes a DOM_SAM_INFO structure. +********************************************************************/ +char* smb_io_sam_info(BOOL io, DOM_SAM_INFO *sam, char *q, char *base, int align) +{ + if (sam == NULL) return NULL; + + q = align_offset(q, base, align); + + q = smb_io_clnt_info(io, &(sam->client ), q, base, align); + q = smb_io_cred (io, &(sam->rtn_cred), q, base, align); + + RW_IVAL(io, q, sam->logon_level, 0); q += 4; + RW_SVAL(io, q, sam->auth_level , 0); q += 4; + + switch (sam->auth_level) + { + case 1: + { + q = smb_io_id_info1(io, &(sam->auth.id1), q, base, align); + break; + } + default: + { + /* PANIC! */ + break; + } + } + return q; +} + +/******************************************************************* +reads or writes a DOM_GID structure. +********************************************************************/ +char* smb_io_gid(BOOL io, DOM_GID *gid, char *q, char *base, int align) +{ + if (gid == NULL) return NULL; + + q = align_offset(q, base, align); + + RW_IVAL(io, q, gid->gid , 0); q += 4; + RW_IVAL(io, q, gid->attr, 0); q += 4; + + return q; +} + +#if 0 +/******************************************************************* +reads or writes a structure. +********************************************************************/ + char* smb_io_(BOOL io, *, char *q, char *base, int align) +{ + if (== NULL) return NULL; + + q = align_offset(q, base, align); + + RW_IVAL(io, q, , 0); q += 4; + + return q; +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ + char* smb_io_(BOOL io, *, char *q, char *base, int align) +{ + if (== NULL) return NULL; + + q = align_offset(q, base, align); + + RW_IVAL(io, q, , 0); q += 4; + + return q; +} +#endif -- cgit