/* * Unix SMB/CIFS implementation. * RPC Pipe client / server routines * Copyright (C) Andrew Tridgell 1992-1997, * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, * Copyright (C) Paul Ashton 1997, * Copyright (C) Jeremy Allison 1999, * Copyright (C) Nigel Williams 2001, * Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2002. * Copyright (C) Gerald (Jerry) Carter 2006. * * 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 3 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, see . */ #include "includes.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_PARSE /******************************************************************* Inits a SESS_INFO_0_STR structure ********************************************************************/ void init_srv_sess_info0( SESS_INFO_0 *ss0, const char *name ) { ZERO_STRUCTP( ss0 ); if ( name ) { if ( (ss0->sharename = TALLOC_P( talloc_tos(), UNISTR2 )) == NULL ) { DEBUG(0,("init_srv_sess_info0: talloc failed!\n")); return; } init_unistr2( ss0->sharename, name, UNI_STR_TERMINATE ); } } /******************************************************************* Reads or writes a structure. ********************************************************************/ static bool srv_io_srv_sess_info_0(const char *desc, SRV_SESS_INFO_0 *ss0, prs_struct *ps, int depth) { if (ss0 == NULL) return False; prs_debug(ps, depth, desc, "srv_io_srv_sess_info_0"); depth++; if(!prs_align(ps)) return False; if(!prs_uint32("num_entries_read", ps, depth, &ss0->num_entries_read)) return False; if(!prs_uint32("ptr_sess_info", ps, depth, &ss0->ptr_sess_info)) return False; if (ss0->ptr_sess_info != 0) { uint32 i; uint32 num_entries = ss0->num_entries_read; if (num_entries > MAX_SESS_ENTRIES) { num_entries = MAX_SESS_ENTRIES; /* report this! */ } if(!prs_uint32("num_entries_read2", ps, depth, &ss0->num_entries_read2)) return False; SMB_ASSERT_ARRAY(ss0->info_0, num_entries); /* first the pointers */ for (i = 0; i < num_entries; i++) { if ( !prs_io_unistr2_p("", ps, depth, &ss0->info_0[i].sharename ) ) return False; } /* now the strings */ for (i = 0; i < num_entries; i++) { if ( !prs_io_unistr2("sharename", ps, depth, ss0->info_0[i].sharename )) return False; } if(!prs_align(ps)) return False; } return True; } /******************************************************************* Inits a SESS_INFO_1 structure ********************************************************************/ void init_srv_sess_info1( SESS_INFO_1 *ss1, const char *name, const char *user, uint32 num_opens, uint32 open_time, uint32 idle_time, uint32 user_flags) { DEBUG(5,("init_srv_sess_info1: %s\n", name)); ZERO_STRUCTP( ss1 ); if ( name ) { if ( (ss1->sharename = TALLOC_P( talloc_tos(), UNISTR2 )) == NULL ) { DEBUG(0,("init_srv_sess_info0: talloc failed!\n")); return; } init_unistr2( ss1->sharename, name, UNI_STR_TERMINATE ); } if ( user ) { if ( (ss1->username = TALLOC_P( talloc_tos(), UNISTR2 )) == NULL ) { DEBUG(0,("init_srv_sess_info0: talloc failed!\n")); return; } init_unistr2( ss1->username, user, UNI_STR_TERMINATE ); } ss1->num_opens = num_opens; ss1->open_time = open_time; ss1->idle_time = idle_time; ss1->user_flags = user_flags; } /******************************************************************* Reads or writes a structure. ********************************************************************/ static bool srv_io_srv_sess_info_1(const char *desc, SRV_SESS_INFO_1 *ss1, prs_struct *ps, int depth) { if (ss1 == NULL) return False; prs_debug(ps, depth, desc, "srv_io_srv_sess_info_1"); depth++; if(!prs_align(ps)) return False; if(!prs_uint32("num_entries_read", ps, depth, &ss1->num_entries_read)) return False; if(!prs_uint32("ptr_sess_info", ps, depth, &ss1->ptr_sess_info)) return False; if (ss1->ptr_sess_info != 0) { uint32 i; uint32 num_entries = ss1->num_entries_read; if (num_entries > MAX_SESS_ENTRIES) { num_entries = MAX_SESS_ENTRIES; /* report this! */ } if(!prs_uint32("num_entries_read2", ps, depth, &ss1->num_entries_read2)) return False; SMB_ASSERT_ARRAY(ss1->info_1, num_entries); /* first the pointers and flags */ for (i = 0; i < num_entries; i++) { if ( !prs_io_unistr2_p("", ps, depth, &ss1->info_1[i].sharename )) return False; if ( !prs_io_unistr2_p("", ps, depth, &ss1->info_1[i].username )) return False; if(!prs_uint32("num_opens ", ps, depth, &ss1->info_1[i].num_opens)) return False; if(!prs_uint32("open_time ", ps, depth, &ss1->info_1[i].open_time)) return False; if(!prs_uint32("idle_time ", ps, depth, &ss1->info_1[i].idle_time)) return False; if(!prs_uint32("user_flags", ps, depth, &ss1->info_1[i].user_flags)) return False; } /* now the strings */ for (i = 0; i < num_entries; i++) { if ( !prs_io_unistr2("", ps, depth, ss1->info_1[i].sharename )) return False; if ( !prs_io_unistr2("", ps, depth, ss1->info_1[i].username )) return False; } if(!prs_align(ps)) return False; } return True; } /******************************************************************* Reads or writes a structure. ********************************************************************/ static bool srv_io_srv_sess_ctr(const char *desc, SRV_SESS_INFO_CTR **pp_ctr, prs_struct *ps, int depth) { SRV_SESS_INFO_CTR *ctr = *pp_ctr; prs_debug(ps, depth, desc, "srv_io_srv_sess_ctr"); depth++; if(UNMARSHALLING(ps)) { ctr = *pp_ctr = PRS_ALLOC_MEM(ps, SRV_SESS_INFO_CTR, 1); if (ctr == NULL) return False; } if (ctr == NULL) return False; if(!prs_align(ps)) return False; if(!prs_uint32("switch_value", ps, depth, &ctr->switch_value)) return False; if(!prs_uint32("ptr_sess_ctr", ps, depth, &ctr->ptr_sess_ctr)) return False; if (ctr->ptr_sess_ctr != 0) { switch (ctr->switch_value) { case 0: if(!srv_io_srv_sess_info_0("", &ctr->sess.info0, ps, depth)) return False; break; case 1: if(!srv_io_srv_sess_info_1("", &ctr->sess.info1, ps, depth)) return False; break; default: DEBUG(5,("%s no session info at switch_value %d\n", tab_depth(5,depth), ctr->switch_value)); break; } } return True; } /******************************************************************* Reads or writes a structure. ********************************************************************/ bool srv_io_q_net_sess_enum(const char *desc, SRV_Q_NET_SESS_ENUM *q_u, prs_struct *ps, int depth) { if (q_u == NULL) return False; prs_debug(ps, depth, desc, "srv_io_q_net_sess_enum"); depth++; if(!prs_align(ps)) return False; if(!prs_pointer("servername", ps, depth, (void*)&q_u->servername, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2)) return False; if(!prs_align(ps)) return False; if(!prs_pointer("qualifier", ps, depth, (void*)&q_u->qualifier, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2)) return False; if(!prs_align(ps)) return False; if(!prs_pointer("username", ps, depth, (void*)&q_u->username, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2)) return False; if(!prs_align(ps)) return False; if(!prs_uint32("sess_level", ps, depth, &q_u->sess_level)) return False; if (q_u->sess_level != (uint32)-1) { if(!srv_io_srv_sess_ctr("sess_ctr", &q_u->ctr, ps, depth)) return False; } if(!prs_uint32("preferred_len", ps, depth, &q_u->preferred_len)) return False; if(!smb_io_enum_hnd("enum_hnd", &q_u->enum_hnd, ps, depth)) return False; return True; } /******************************************************************* Reads or writes a structure. ********************************************************************/ bool srv_io_r_net_sess_enum(const char *desc, SRV_R_NET_SESS_ENUM *r_n, prs_struct *ps, int depth) { if (r_n == NULL) return False; prs_debug(ps, depth, desc, "srv_io_r_net_sess_enum"); depth++; if(!prs_align(ps)) return False; if(!prs_uint32("sess_level", ps, depth, &r_n->sess_level)) return False; if (r_n->sess_level != (uint32)-1) { if(!srv_io_srv_sess_ctr("sess_ctr", &r_n->ctr, ps, depth)) return False; } if(!prs_uint32("total_entries", ps, depth, &r_n->total_entries)) return False; if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth)) return False; if(!prs_werror("status", ps, depth, &r_n->status)) return False; return True; }