From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/rpc_parse/parse_dfs.c | 3 + source3/rpc_parse/parse_lsa.c | 78 ++-- source3/rpc_parse/parse_misc.c | 53 ++- source3/rpc_parse/parse_net.c | 14 +- source3/rpc_parse/parse_prs.c | 37 +- source3/rpc_parse/parse_reg.c | 80 ++-- source3/rpc_parse/parse_rpc.c | 3 + source3/rpc_parse/parse_samr.c | 188 ++++++++-- source3/rpc_parse/parse_sec.c | 109 +++--- source3/rpc_parse/parse_spoolss.c | 744 ++++++++++++++++++++++++++++++++------ source3/rpc_parse/parse_srv.c | 272 ++++++++++---- source3/rpc_parse/parse_wks.c | 3 + 12 files changed, 1244 insertions(+), 340 deletions(-) (limited to 'source3/rpc_parse') diff --git a/source3/rpc_parse/parse_dfs.c b/source3/rpc_parse/parse_dfs.c index 6c83963d7a..38633ac0f7 100644 --- a/source3/rpc_parse/parse_dfs.c +++ b/source3/rpc_parse/parse_dfs.c @@ -25,6 +25,9 @@ #include "nterr.h" #include "rpc_parse.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_PARSE + /******************************************************************* Make a DFS_Q_DFS_QUERY structure *******************************************************************/ diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c index 91b54b9c83..a6aecb7967 100644 --- a/source3/rpc_parse/parse_lsa.c +++ b/source3/rpc_parse/parse_lsa.c @@ -4,6 +4,7 @@ * Copyright (C) Andrew Tridgell 1992-1997, * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, * Copyright (C) Paul Ashton 1997. + * Copyright (C) Andrew Bartlett 2002. * * 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 @@ -22,6 +23,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_PARSE + static BOOL lsa_io_trans_names(char *desc, LSA_TRANS_NAME_ENUM *trn, prs_struct *ps, int depth); /******************************************************************* @@ -188,7 +192,7 @@ static BOOL lsa_io_sec_qos(char *desc, LSA_SEC_QOS *qos, prs_struct *ps, Inits an LSA_OBJ_ATTR structure. ********************************************************************/ -void init_lsa_obj_attr(LSA_OBJ_ATTR *attr, uint32 attributes, LSA_SEC_QOS *qos) +static void init_lsa_obj_attr(LSA_OBJ_ATTR *attr, uint32 attributes, LSA_SEC_QOS *qos) { DEBUG(5, ("init_lsa_obj_attr\n")); @@ -523,40 +527,52 @@ BOOL lsa_io_q_enum_trust_dom(char *desc, LSA_Q_ENUM_TRUST_DOM *q_e, Inits an LSA_R_ENUM_TRUST_DOM structure. ********************************************************************/ -void init_r_enum_trust_dom(TALLOC_CTX *ctx, LSA_R_ENUM_TRUST_DOM *r_e, uint32 enum_context, - char *domain_name, DOM_SID *domain_sid, - NTSTATUS status) +void init_r_enum_trust_dom(TALLOC_CTX *ctx, LSA_R_ENUM_TRUST_DOM *r_e, uint32 enum_context, + uint32 req_num_domains, uint32 num_domains, TRUSTDOM **td) { + int i; + DEBUG(5, ("init_r_enum_trust_dom\n")); r_e->enum_context = enum_context; + r_e->num_domains = num_domains; + r_e->ptr_enum_domains = 0; + r_e->num_domains2 = num_domains; - if (NT_STATUS_IS_OK(status)) { - int len_domain_name = strlen(domain_name) + 1; - - r_e->num_domains = 1; - r_e->ptr_enum_domains = 1; - r_e->num_domains2 = 1; - - if (!(r_e->hdr_domain_name = (UNIHDR2 *)talloc(ctx,sizeof(UNIHDR2)))) + if (num_domains != 0) { + + /* + * allocating empty arrays of unicode headers, strings + * and sids of enumerated trusted domains + */ + if (!(r_e->hdr_domain_name = (UNIHDR2 *)talloc(ctx,sizeof(UNIHDR2) * num_domains))) { + r_e->status = NT_STATUS_NO_MEMORY; return; - - if (!(r_e->uni_domain_name = (UNISTR2 *)talloc(ctx,sizeof(UNISTR2)))) + } + + if (!(r_e->uni_domain_name = (UNISTR2 *)talloc(ctx,sizeof(UNISTR2) * num_domains))) { + r_e->status = NT_STATUS_NO_MEMORY; return; + } - if (!(r_e->domain_sid = (DOM_SID2 *)talloc(ctx,sizeof(DOM_SID2)))) + if (!(r_e->domain_sid = (DOM_SID2 *)talloc(ctx,sizeof(DOM_SID2) * num_domains))) { + r_e->status = NT_STATUS_NO_MEMORY; return; + } + + for (i = 0; i < num_domains; i++) { + + /* don't know what actually is this for */ + r_e->ptr_enum_domains = 1; + + init_uni_hdr2(&r_e->hdr_domain_name[i], strlen_w((td[i])->name)); + init_dom_sid2(&r_e->domain_sid[i], &(td[i])->sid); + + init_unistr2_w(ctx, &r_e->uni_domain_name[i], (td[i])->name); + + }; + } - init_uni_hdr2(&r_e->hdr_domain_name[0], len_domain_name); - init_unistr2 (&r_e->uni_domain_name[0], domain_name, - len_domain_name); - init_dom_sid2(&r_e->domain_sid[0], domain_sid); - } else { - r_e->num_domains = 0; - r_e->ptr_enum_domains = 0; - } - - r_e->status = status; } /******************************************************************* @@ -603,7 +619,7 @@ BOOL lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM *r_e, for (i = 0; i < num_domains; i++) { if(!smb_io_unistr2 ("", &r_e->uni_domain_name[i], - r_e->hdr_domain_name[i].buffer, + r_e->hdr_domain_name[i].buffer, ps, depth)) return False; if(!smb_io_dom_sid2("", &r_e->domain_sid[i], ps, @@ -713,7 +729,7 @@ static BOOL lsa_io_dom_query_3(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int Reads or writes a dom query structure. ********************************************************************/ -BOOL lsa_io_dom_query_5(char *desc, DOM_QUERY_5 *d_q, prs_struct *ps, int depth) +static BOOL lsa_io_dom_query_5(char *desc, DOM_QUERY_5 *d_q, prs_struct *ps, int depth) { return lsa_io_dom_query("", d_q, ps, depth); } @@ -792,7 +808,7 @@ BOOL lsa_io_r_query(char *desc, LSA_R_QUERY_INFO *r_q, prs_struct *ps, Inits a LSA_SID_ENUM structure. ********************************************************************/ -void init_lsa_sid_enum(TALLOC_CTX *mem_ctx, LSA_SID_ENUM *sen, +static void init_lsa_sid_enum(TALLOC_CTX *mem_ctx, LSA_SID_ENUM *sen, int num_entries, DOM_SID *sids) { int i; @@ -1737,7 +1753,7 @@ BOOL lsa_io_q_enum_privsaccount(char *desc, LSA_Q_ENUMPRIVSACCOUNT *r_c, prs_str Reads or writes an LUID structure. ********************************************************************/ -BOOL lsa_io_luid(char *desc, LUID *r_c, prs_struct *ps, int depth) +static BOOL lsa_io_luid(char *desc, LUID *r_c, prs_struct *ps, int depth) { prs_debug(ps, depth, desc, "lsa_io_luid"); depth++; @@ -1758,7 +1774,7 @@ BOOL lsa_io_luid(char *desc, LUID *r_c, prs_struct *ps, int depth) Reads or writes an LUID_ATTR structure. ********************************************************************/ -BOOL lsa_io_luid_attr(char *desc, LUID_ATTR *r_c, prs_struct *ps, int depth) +static BOOL lsa_io_luid_attr(char *desc, LUID_ATTR *r_c, prs_struct *ps, int depth) { prs_debug(ps, depth, desc, "lsa_io_luid_attr"); depth++; @@ -1779,7 +1795,7 @@ BOOL lsa_io_luid_attr(char *desc, LUID_ATTR *r_c, prs_struct *ps, int depth) Reads or writes an PRIVILEGE_SET structure. ********************************************************************/ -BOOL lsa_io_privilege_set(char *desc, PRIVILEGE_SET *r_c, prs_struct *ps, int depth) +static BOOL lsa_io_privilege_set(char *desc, PRIVILEGE_SET *r_c, prs_struct *ps, int depth) { uint32 i; diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c index 73f285e320..01d7698173 100644 --- a/source3/rpc_parse/parse_misc.c +++ b/source3/rpc_parse/parse_misc.c @@ -22,6 +22,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_PARSE + /**************************************************************************** A temporary TALLOC context for things like unistrs, that is valid for the life of a complete RPC call. @@ -211,9 +214,6 @@ BOOL smb_io_dom_sid(char *desc, DOM_SID *sid, prs_struct *ps, int depth) prs_debug(ps, depth, desc, "smb_io_dom_sid"); depth++; - if(!prs_align(ps)) - return False; - if(!prs_uint8 ("sid_rev_num", ps, depth, &sid->sid_rev_num)) return False; if(!prs_uint8 ("num_auths ", ps, depth, &sid->num_auths)) @@ -551,8 +551,6 @@ BOOL smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth) prs_debug(ps, depth, desc, "smb_io_unistr"); depth++; - if(!prs_align(ps)) - return False; if(!prs_unistr("unistr", ps, depth, uni)) return False; @@ -916,6 +914,51 @@ void init_unistr2(UNISTR2 *str, const char *buf, size_t len) rpcstr_push((char *)str->buffer, buf, len, STR_TERMINATE); } +/** + * Inits a UNISTR2 structure. + * @param ctx talloc context to allocate string on + * @param str pointer to string to create + * @param buf UCS2 null-terminated buffer to init from +*/ + +void init_unistr2_w(TALLOC_CTX *ctx, UNISTR2 *str, const smb_ucs2_t *buf) +{ + uint32 len = strlen_w(buf); + uint32 max_len = len; + uint32 alloc_len; + + ZERO_STRUCTP(str); + + /* set up string lengths. */ + str->uni_max_len = len; + str->undoc = 0; + str->uni_str_len = len; + + if (max_len < MAX_UNISTRLEN) + max_len = MAX_UNISTRLEN; + + alloc_len = (max_len + 1) * sizeof(uint16); + + str->buffer = (uint16 *)talloc_zero(ctx, alloc_len); + if ((str->buffer == NULL) && (alloc_len > 0)) + { + smb_panic("init_unistr2_w: malloc fail\n"); + return; + } + + /* + * don't move this test above ! The UNISTR2 must be initialized !!! + * jfm, 7/7/2001. + */ + if (buf==NULL) + return; + + /* Yes, this is a strncpy( foo, bar, strlen(bar)) - but as + long as the buffer above is talloc()ed correctly then this + is the correct thing to do */ + strncpy_w(str->buffer, buf, len + 1); +} + /******************************************************************* Inits a UNISTR2 structure from a UNISTR ********************************************************************/ diff --git a/source3/rpc_parse/parse_net.c b/source3/rpc_parse/parse_net.c index afbdf6dc57..46fdce63ff 100644 --- a/source3/rpc_parse/parse_net.c +++ b/source3/rpc_parse/parse_net.c @@ -22,6 +22,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_PARSE + /******************************************************************* Reads or writes a structure. ********************************************************************/ @@ -1218,10 +1221,10 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, time_t unix_pass_must_change_time, uint16 logon_count, uint16 bad_pw_count, - uint32 num_groups, DOM_GID *gids, + uint32 num_groups, const DOM_GID *gids, uint32 user_flgs, uchar *sess_key, - char *logon_srv, char *logon_dom, - DOM_SID *dom_sid, char *other_sids) + const char *logon_srv, const char *logon_dom, + const DOM_SID *dom_sid, char *other_sids) { /* only cope with one "other" sid, right now. */ /* need to count the number of space-delimited sids */ @@ -1331,14 +1334,15 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, Jacobsen at HP. JRA. ********************************************************************/ -static BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, int depth, uint16 validation_level) +BOOL net_io_user_info3(const char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, + int depth, uint16 validation_level) { int i; if (usr == NULL) return False; - prs_debug(ps, depth, desc, "lsa_io_lsa_user_info"); + prs_debug(ps, depth, desc, "net_io_user_info3"); depth++; if (UNMARSHALLING(ps)) diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c index 6d65d5cc7f..2ab8c7246e 100644 --- a/source3/rpc_parse/parse_prs.c +++ b/source3/rpc_parse/parse_prs.c @@ -22,6 +22,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_PARSE + /** * Dump a prs to a file: from the current location through to the end. **/ @@ -73,7 +76,7 @@ void prs_dump_region(char *name, int v, prs_struct *ps, XXXX side-effect of this function is to increase the debug depth XXXX ********************************************************************/ -void prs_debug(prs_struct *ps, int depth, char *desc, char *fn_name) +void prs_debug(prs_struct *ps, int depth, const char *desc, char *fn_name) { DEBUG(5+depth, ("%s%06x %s %s\n", tab_depth(depth), ps->data_offset, fn_name, desc)); } @@ -444,6 +447,38 @@ BOOL prs_align(prs_struct *ps) return True; } +/****************************************************************** + Align on a 2 byte boundary + *****************************************************************/ + +BOOL prs_align_uint16(prs_struct *ps) +{ + BOOL ret; + uint8 old_align = ps->align; + + ps->align = 2; + ret = prs_align(ps); + ps->align = old_align; + + return ret; +} + +/****************************************************************** + Align on a 8 byte boundary + *****************************************************************/ + +BOOL prs_align_uint64(prs_struct *ps) +{ + BOOL ret; + uint8 old_align = ps->align; + + ps->align = 8; + ret = prs_align(ps); + ps->align = old_align; + + return ret; +} + /******************************************************************* Align only if required (for the unistr2 string mainly) ********************************************************************/ diff --git a/source3/rpc_parse/parse_reg.c b/source3/rpc_parse/parse_reg.c index 1b8d1cd5c8..1ebc1532f3 100644 --- a/source3/rpc_parse/parse_reg.c +++ b/source3/rpc_parse/parse_reg.c @@ -24,6 +24,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_PARSE + /******************************************************************* Inits a structure. ********************************************************************/ @@ -126,11 +129,11 @@ BOOL reg_io_q_open_hklm(char *desc, REG_Q_OPEN_HKLM * r_q, prs_struct *ps, if (r_q->ptr != 0) { if (!prs_uint16("unknown_0", ps, depth, &(r_q->unknown_0))) - return False; + return False; if (!prs_uint16("unknown_1", ps, depth, &(r_q->unknown_1))) - return False; + return False; if (!prs_uint32("access_mask", ps, depth, &(r_q->access_mask))) - return False; + return False; } return True; @@ -568,7 +571,7 @@ BOOL reg_io_r_query_key(char *desc, REG_R_QUERY_KEY *r_r, prs_struct *ps, int d return False; if(!prs_uint32("max_subkeylen ", ps, depth, &r_r->max_subkeylen)) return False; - if(!prs_uint32("mak_subkeysize", ps, depth, &r_r->max_subkeysize)) + if(!prs_uint32("reserved ", ps, depth, &r_r->reserved)) return False; if(!prs_uint32("num_values ", ps, depth, &r_r->num_values)) return False; @@ -591,7 +594,7 @@ BOOL reg_io_r_query_key(char *desc, REG_R_QUERY_KEY *r_r, prs_struct *ps, int d Inits a structure. ********************************************************************/ -void init_reg_q_unk_1a(REG_Q_UNK_1A *q_o, POLICY_HND *hnd) +void init_reg_q_unknown_1a(REG_Q_UNKNOWN_1A *q_o, POLICY_HND *hnd) { memcpy(&q_o->pol, hnd, sizeof(q_o->pol)); } @@ -600,12 +603,12 @@ void init_reg_q_unk_1a(REG_Q_UNK_1A *q_o, POLICY_HND *hnd) reads or writes a structure. ********************************************************************/ -BOOL reg_io_q_unk_1a(char *desc, REG_Q_UNK_1A *r_q, prs_struct *ps, int depth) +BOOL reg_io_q_unknown_1a(char *desc, REG_Q_UNKNOWN_1A *r_q, prs_struct *ps, int depth) { if (r_q == NULL) return False; - prs_debug(ps, depth, desc, "reg_io_q_unk_1a"); + prs_debug(ps, depth, desc, "reg_io_q_unknown_1a"); depth++; if(!prs_align(ps)) @@ -621,12 +624,12 @@ BOOL reg_io_q_unk_1a(char *desc, REG_Q_UNK_1A *r_q, prs_struct *ps, int depth) reads or writes a structure. ********************************************************************/ -BOOL reg_io_r_unk_1a(char *desc, REG_R_UNK_1A *r_r, prs_struct *ps, int depth) +BOOL reg_io_r_unknown_1a(char *desc, REG_R_UNKNOWN_1A *r_r, prs_struct *ps, int depth) { if (r_r == NULL) return False; - prs_debug(ps, depth, desc, "reg_io_r_unk_1a"); + prs_debug(ps, depth, desc, "reg_io_r_unknown_1a"); depth++; if(!prs_align(ps)) @@ -645,12 +648,12 @@ BOOL reg_io_r_unk_1a(char *desc, REG_R_UNK_1A *r_r, prs_struct *ps, int depth) ********************************************************************/ void init_reg_q_open_hku(REG_Q_OPEN_HKU *q_o, - uint16 unknown_0, uint32 level) + uint16 unknown_0, uint32 access_mask) { q_o->ptr = 1; q_o->unknown_0 = unknown_0; q_o->unknown_1 = 0x0; /* random - changes */ - q_o->level = level; + q_o->access_mask = access_mask; } /******************************************************************* @@ -671,11 +674,11 @@ BOOL reg_io_q_open_hku(char *desc, REG_Q_OPEN_HKU *r_q, prs_struct *ps, int dep if(!prs_uint32("ptr ", ps, depth, &r_q->ptr)) return False; if (r_q->ptr != 0) { - if(!prs_uint16("unknown_0", ps, depth, &r_q->unknown_0)) + if(!prs_uint16("unknown_0 ", ps, depth, &r_q->unknown_0)) return False; - if(!prs_uint16("unknown_1", ps, depth, &r_q->unknown_1)) + if(!prs_uint16("unknown_1 ", ps, depth, &r_q->unknown_1)) return False; - if(!prs_uint32("level ", ps, depth, &r_q->level)) + if(!prs_uint32("access_mask ", ps, depth, &r_q->access_mask)) return False; } @@ -726,7 +729,7 @@ BOOL reg_io_q_close(char *desc, REG_Q_CLOSE *q_u, prs_struct *ps, int depth) if (q_u == NULL) return False; - prs_debug(ps, depth, desc, "reg_io_q_unknown_1"); + prs_debug(ps, depth, desc, "reg_io_q_close"); depth++; if(!prs_align(ps)) @@ -749,7 +752,7 @@ BOOL reg_io_r_close(char *desc, REG_R_CLOSE *r_u, prs_struct *ps, int depth) if (r_u == NULL) return False; - prs_debug(ps, depth, desc, "reg_io_r_unknown_1"); + prs_debug(ps, depth, desc, "reg_io_r_close"); depth++; if(!prs_align(ps)) @@ -1007,13 +1010,15 @@ BOOL reg_io_q_info(char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth) if(!prs_uint32("ptr_buflen", ps, depth, &(r_q->ptr_buflen))) return False; - if(!prs_uint32("buflen", ps, depth, &(r_q->buflen))) - return False; - if(!prs_uint32("ptr_buflen2", ps, depth, &(r_q->ptr_buflen2))) - return False; - if(!prs_uint32("buflen2", ps, depth, &(r_q->buflen2))) - return False; + if (r_q->ptr_buflen) { + if(!prs_uint32("buflen", ps, depth, &(r_q->buflen))) + return False; + if(!prs_uint32("ptr_buflen2", ps, depth, &(r_q->ptr_buflen2))) + return False; + if(!prs_uint32("buflen2", ps, depth, &(r_q->buflen2))) + return False; + } return True; } @@ -1348,6 +1353,29 @@ void init_reg_q_enum_key(REG_Q_ENUM_KEY *q_i, POLICY_HND *pol, uint32 key_idx) unix_to_nt_time(&q_i->time, 0); /* current time? */ } +/******************************************************************* +makes a reply structure. +********************************************************************/ + +void init_reg_r_enum_key(REG_R_ENUM_KEY *r_u, char *subkey, uint32 unknown_1, + uint32 unknown_2) +{ + if ( !r_u ) + return; + + r_u->unknown_1 = unknown_1; + r_u->unknown_2 = unknown_2; + r_u->unknown_3 = 0x0; + + r_u->key_name_len = (strlen(subkey)+1) * 2; + if (r_u->key_name_len) + r_u->ptr1 = 0x1; + init_unistr3( &r_u->key_name, subkey ); + + r_u->ptr2 = 0x1; + r_u->ptr3 = 0x1; +} + /******************************************************************* reads or writes a structure. ********************************************************************/ @@ -1463,7 +1491,7 @@ makes a structure. ********************************************************************/ void init_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q, POLICY_HND *pol, - char *key_name, uint32 unk) + char *key_name, uint32 access_desired) { int len_name = strlen(key_name)+1; @@ -1473,7 +1501,7 @@ void init_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q, POLICY_HND *pol, init_unistr2(&r_q->uni_name, key_name, len_name); r_q->unknown_0 = 0x00000000; - r_q->unknown_1 = unk; + r_q->access_desired = access_desired; } /******************************************************************* @@ -1501,9 +1529,9 @@ BOOL reg_io_q_open_entry(char *desc, REG_Q_OPEN_ENTRY *r_q, prs_struct *ps, int if(!prs_align(ps)) return False; - if(!prs_uint32("unknown_0", ps, depth, &r_q->unknown_0)) + if(!prs_uint32("unknown_0 ", ps, depth, &r_q->unknown_0)) return False; - if(!prs_uint32("unknown_1", ps, depth, &r_q->unknown_1)) + if(!prs_uint32("asccess_desired ", ps, depth, &r_q->access_desired)) return False; return True; diff --git a/source3/rpc_parse/parse_rpc.c b/source3/rpc_parse/parse_rpc.c index ee15d7cded..41e0b4cb5f 100644 --- a/source3/rpc_parse/parse_rpc.c +++ b/source3/rpc_parse/parse_rpc.c @@ -23,6 +23,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_PARSE + /******************************************************************* interface/version dce/rpc pipe identification ********************************************************************/ diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index 4edc0678af..c16232204c 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -27,6 +27,9 @@ #include "rpc_parse.h" #include "nterr.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_PARSE + /******************************************************************* inits a SAMR_Q_CLOSE_HND structure. ********************************************************************/ @@ -387,6 +390,36 @@ BOOL samr_io_r_get_usrdom_pwinfo(char *desc, SAMR_R_GET_USRDOM_PWINFO * r_u, return True; } + +/******************************************************************* +reads or writes a structure. +********************************************************************/ + +BOOL samr_io_q_set_sec_obj(char *desc, SAMR_Q_SET_SEC_OBJ * q_u, + prs_struct *ps, int depth) +{ + if (q_u == NULL) + return False; + + prs_debug(ps, depth, desc, "samr_io_q_set_sec_obj"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth)) + return False; + + if(!prs_uint32("sec_info", ps, depth, &q_u->sec_info)) + return False; + + if(!sec_io_desc_buf("sec_desc", &q_u->buf, ps, depth)) + return False; + + return True; +} + + /******************************************************************* reads or writes a structure. ********************************************************************/ @@ -861,6 +894,28 @@ BOOL samr_io_r_query_dom_info(char *desc, SAMR_R_QUERY_DOMAIN_INFO * r_u, return True; } +/******************************************************************* +reads or writes a SAMR_R_SET_SEC_OBJ structure. +********************************************************************/ + +BOOL samr_io_r_set_sec_obj(char *desc, SAMR_R_SET_SEC_OBJ * r_u, + prs_struct *ps, int depth) +{ + if (r_u == NULL) + return False; + + prs_debug(ps, depth, desc, "samr_io_r_set_sec_obj"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_ntstatus("status", ps, depth, &r_u->status)) + return False; + + return True; +} + /******************************************************************* reads or writes a SAMR_R_QUERY_SEC_OBJ structure. ********************************************************************/ @@ -1437,7 +1492,8 @@ inits a SAM_DISPINFO_1 structure. ********************************************************************/ NTSTATUS init_sam_dispinfo_1(TALLOC_CTX *ctx, SAM_DISPINFO_1 *sam, uint32 num_entries, - uint32 start_idx, DISP_USER_INFO *disp_user_info) + uint32 start_idx, DISP_USER_INFO *disp_user_info, + DOM_SID *domain_sid) { uint32 len_sam_name, len_sam_full, len_sam_desc; uint32 i; @@ -1462,18 +1518,49 @@ NTSTATUS init_sam_dispinfo_1(TALLOC_CTX *ctx, SAM_DISPINFO_1 *sam, uint32 num_en ZERO_STRUCTP(sam->str); for (i = 0; i < num_entries ; i++) { + const char *username; + const char *fullname; + const char *acct_desc; + uint32 user_rid; + const DOM_SID *user_sid; + fstring user_sid_string, domain_sid_string; + DEBUG(11, ("init_sam_dispinfo_1: entry: %d\n",i)); pwd=disp_user_info[i+start_idx].sam; - len_sam_name = strlen(pdb_get_username(pwd)); - len_sam_full = strlen(pdb_get_fullname(pwd)); - len_sam_desc = strlen(pdb_get_acct_desc(pwd)); + username = pdb_get_username(pwd); + fullname = pdb_get_fullname(pwd); + acct_desc = pdb_get_acct_desc(pwd); + + if (!username) + username = ""; + + if (!fullname) + fullname = ""; + + if (!acct_desc) + acct_desc = ""; + + user_sid = pdb_get_user_sid(pwd); + + if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) { + DEBUG(0, ("init_sam_dispinfo_1: User %s has SID %s, which conflicts with " + "the domain sid %s. Failing operation.\n", + username, + sid_to_string(user_sid_string, user_sid), + sid_to_string(domain_sid_string, domain_sid))); + return NT_STATUS_UNSUCCESSFUL; + } + + len_sam_name = strlen(username); + len_sam_full = strlen(fullname); + len_sam_desc = strlen(acct_desc); init_sam_entry1(&sam->sam[i], start_idx + i + 1, len_sam_name, len_sam_full, len_sam_desc, - pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd)); - + user_rid, pdb_get_acct_ctrl(pwd)); + ZERO_STRUCTP(&sam->str[i].uni_acct_name); ZERO_STRUCTP(&sam->str[i].uni_full_name); ZERO_STRUCTP(&sam->str[i].uni_acct_desc); @@ -1540,7 +1627,8 @@ inits a SAM_DISPINFO_2 structure. ********************************************************************/ NTSTATUS init_sam_dispinfo_2(TALLOC_CTX *ctx, SAM_DISPINFO_2 *sam, uint32 num_entries, - uint32 start_idx, DISP_USER_INFO *disp_user_info) + uint32 start_idx, DISP_USER_INFO *disp_user_info, + DOM_SID *domain_sid ) { uint32 len_sam_name, len_sam_desc; uint32 i; @@ -1563,20 +1651,39 @@ NTSTATUS init_sam_dispinfo_2(TALLOC_CTX *ctx, SAM_DISPINFO_2 *sam, uint32 num_en ZERO_STRUCTP(sam->str); for (i = 0; i < num_entries; i++) { + uint32 user_rid; + const DOM_SID *user_sid; + const char *username; + const char *acct_desc; + fstring user_sid_string, domain_sid_string; + DEBUG(11, ("init_sam_dispinfo_2: entry: %d\n",i)); pwd=disp_user_info[i+start_idx].sam; - len_sam_name = strlen(pdb_get_username(pwd)); - len_sam_desc = strlen(pdb_get_acct_desc(pwd)); + username = pdb_get_username(pwd); + acct_desc = pdb_get_acct_desc(pwd); + user_sid = pdb_get_user_sid(pwd); + + if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) { + DEBUG(0, ("init_sam_dispinfo_2: User %s has SID %s, which conflicts with " + "the domain sid %s. Failing operation.\n", + username, + sid_to_string(user_sid_string, user_sid), + sid_to_string(domain_sid_string, domain_sid))); + return NT_STATUS_UNSUCCESSFUL; + } + + len_sam_name = strlen(username); + len_sam_desc = strlen(acct_desc); init_sam_entry2(&sam->sam[i], start_idx + i + 1, len_sam_name, len_sam_desc, - pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd)); + user_rid, pdb_get_acct_ctrl(pwd)); ZERO_STRUCTP(&sam->str[i].uni_srv_name); ZERO_STRUCTP(&sam->str[i].uni_srv_desc); - init_unistr2(&sam->str[i].uni_srv_name, pdb_get_username(pwd), len_sam_name); + init_unistr2(&sam->str[i].uni_srv_name, username, len_sam_name); init_unistr2(&sam->str[i].uni_srv_desc, pdb_get_acct_desc(pwd), len_sam_desc); } @@ -4535,7 +4642,7 @@ inits a SAMR_Q_LOOKUP_NAMES structure. NTSTATUS init_samr_q_lookup_names(TALLOC_CTX *ctx, SAMR_Q_LOOKUP_NAMES * q_u, POLICY_HND *pol, uint32 flags, - uint32 num_names, char **name) + uint32 num_names, const char **name) { uint32 i; @@ -5824,7 +5931,7 @@ void init_sam_user_info21W(SAM_USER_INFO_21 * usr, *************************************************************************/ -void init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw) +NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID *domain_sid) { NTTIME logon_time, logoff_time, kickoff_time, pass_last_set_time, pass_can_change_time, @@ -5845,6 +5952,12 @@ void init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw) const char* workstations = pdb_get_workstations(pw); const char* munged_dial = pdb_get_munged_dial(pw); + uint32 user_rid; + const DOM_SID *user_sid; + + uint32 group_rid; + const DOM_SID *group_sid; + len_user_name = user_name != NULL ? strlen(user_name )+1 : 0; len_full_name = full_name != NULL ? strlen(full_name )+1 : 0; len_home_dir = home_dir != NULL ? strlen(home_dir )+1 : 0; @@ -5887,8 +6000,34 @@ void init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw) ZERO_STRUCT(usr->nt_pwd); ZERO_STRUCT(usr->lm_pwd); - usr->user_rid = pdb_get_user_rid(pw); - usr->group_rid = pdb_get_group_rid(pw); + user_sid = pdb_get_user_sid(pw); + + if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) { + fstring user_sid_string; + fstring domain_sid_string; + DEBUG(0, ("init_sam_user_info_21A: User %s has SID %s, \nwhich conflicts with " + "the domain sid %s. Failing operation.\n", + user_name, + sid_to_string(user_sid_string, user_sid), + sid_to_string(domain_sid_string, domain_sid))); + return NT_STATUS_UNSUCCESSFUL; + } + + group_sid = pdb_get_group_sid(pw); + + if (!sid_peek_check_rid(domain_sid, group_sid, &group_rid)) { + fstring group_sid_string; + fstring domain_sid_string; + DEBUG(0, ("init_sam_user_info_21A: User %s has Primary Group SID %s, \n" + "which conflicts with the domain sid %s. Failing operation.\n", + user_name, + sid_to_string(group_sid_string, group_sid), + sid_to_string(domain_sid_string, domain_sid))); + return NT_STATUS_UNSUCCESSFUL; + } + + usr->user_rid = user_rid; + usr->group_rid = group_rid; usr->acb_info = pdb_get_acct_ctrl(pw); usr->unknown_3 = pdb_get_unknown3(pw); @@ -5917,6 +6056,8 @@ void init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw) memcpy(&usr->logon_hrs.hours, pdb_get_hours(pw), MAX_HOURS_LEN); } else memset(&usr->logon_hrs, 0xff, sizeof(usr->logon_hrs)); + + return NT_STATUS_OK; } /******************************************************************* @@ -6702,17 +6843,16 @@ BOOL samr_io_r_get_dom_pwinfo(char *desc, SAMR_R_GET_DOM_PWINFO * r_u, if(!prs_align(ps)) return False; - if(!prs_uint16("unk_0", ps, depth, &r_u->unk_0)) - return False; - if(!prs_align(ps)) - return False; - if(!prs_uint16("unk_1", ps, depth, &r_u->unk_1)) - return False; - if(!prs_align(ps)) + /* + * We need 16 bytes here according to tests. Don't know + * what they are, but the length is important for the singing + */ + + if(!prs_uint32("unk_0", ps, depth, &r_u->unk_0)) return False; - if(!prs_uint16("unk_2", ps, depth, &r_u->unk_2)) + if(!prs_uint32("unk_1", ps, depth, &r_u->unk_1)) return False; - if(!prs_align(ps)) + if(!prs_uint32("unk_2", ps, depth, &r_u->unk_2)) return False; if(!prs_ntstatus("status", ps, depth, &r_u->status)) diff --git a/source3/rpc_parse/parse_sec.c b/source3/rpc_parse/parse_sec.c index 4f093b2422..56eaf4c5b5 100644 --- a/source3/rpc_parse/parse_sec.c +++ b/source3/rpc_parse/parse_sec.c @@ -1,5 +1,6 @@ /* - * Unix SMB/CIFS implementation. + * Unix SMB/Netbios implementation. + * Version 1.9. * RPC Pipe client / server routines * Copyright (C) Andrew Tridgell 1992-1998, * Copyright (C) Jeremy R. Allison 1995-1998 @@ -23,6 +24,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_PARSE + /******************************************************************* Sets up a SEC_ACCESS structure. ********************************************************************/ @@ -43,9 +47,6 @@ BOOL sec_io_access(char *desc, SEC_ACCESS *t, prs_struct *ps, int depth) prs_debug(ps, depth, desc, "sec_io_access"); depth++; - - if(!prs_align(ps)) - return False; if(!prs_uint32("mask", ps, depth, &(t->mask))) return False; @@ -112,9 +113,6 @@ BOOL sec_io_ace(char *desc, SEC_ACE *psa, prs_struct *ps, int depth) prs_debug(ps, depth, desc, "sec_io_ace"); depth++; - - if(!prs_align(ps)) - return False; old_offset = prs_offset(ps); @@ -130,9 +128,6 @@ BOOL sec_io_ace(char *desc, SEC_ACE *psa, prs_struct *ps, int depth) if(!sec_io_access("info ", &psa->info, ps, depth)) return False; - if(!prs_align(ps)) - return False; - /* check whether object access is present */ if (!sec_ace_object(psa->type)) { if (!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth)) @@ -293,6 +288,13 @@ BOOL sec_io_acl(char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth) uint32 offset_acl_size; SEC_ACL *psa; + /* + * Note that the size is always a multiple of 4 bytes due to the + * nature of the data structure. Therefore the prs_align() calls + * have been removed as they through us off when doing two-layer + * marshalling such as in the printing code (NEW_BUFFER). --jerry + */ + if (ppsa == NULL) return False; @@ -309,9 +311,6 @@ BOOL sec_io_acl(char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth) prs_debug(ps, depth, desc, "sec_io_acl"); depth++; - - if(!prs_align(ps)) - return False; old_offset = prs_offset(ps); @@ -341,9 +340,6 @@ BOOL sec_io_acl(char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth) return False; } - if(!prs_align(ps)) - return False; - if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_acl_size, old_offset)) return False; @@ -362,17 +358,19 @@ size_t sec_desc_size(SEC_DESC *psd) offset = SEC_DESC_HEADER_SIZE; + /* don't align */ + if (psd->owner_sid != NULL) - offset += ((sid_size(psd->owner_sid) + 3) & ~3); + offset += sid_size(psd->owner_sid); if (psd->grp_sid != NULL) - offset += ((sid_size(psd->grp_sid) + 3) & ~3); + offset += sid_size(psd->grp_sid); if (psd->sacl != NULL) - offset += ((psd->sacl->size + 3) & ~3); + offset += psd->sacl->size; if (psd->dacl != NULL) - offset += ((psd->dacl->size + 3) & ~3); + offset += psd->dacl->size; return offset; } @@ -640,7 +638,7 @@ SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision, if (offset == 0) offset = SEC_DESC_HEADER_SIZE; - offset += ((sid_size(dst->owner_sid) + 3) & ~3); + offset += sid_size(dst->owner_sid); } if (dst->grp_sid != NULL) { @@ -648,7 +646,7 @@ SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision, if (offset == 0) offset = SEC_DESC_HEADER_SIZE; - offset += ((sid_size(dst->grp_sid) + 3) & ~3); + offset += sid_size(dst->grp_sid); } if (dst->sacl != NULL) { @@ -656,7 +654,7 @@ SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision, offset_acl = SEC_DESC_HEADER_SIZE; dst->off_sacl = offset_acl; - offset_acl += ((dst->sacl->size + 3) & ~3); + offset_acl += dst->sacl->size; offset += dst->sacl->size; offset_sid += dst->sacl->size; } @@ -667,19 +665,20 @@ SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision, offset_acl = SEC_DESC_HEADER_SIZE; dst->off_dacl = offset_acl; - offset_acl += ((dst->dacl->size + 3) & ~3); + offset_acl += dst->dacl->size; offset += dst->dacl->size; offset_sid += dst->dacl->size; } *sd_size = (size_t)((offset == 0) ? SEC_DESC_HEADER_SIZE : offset); - dst->off_owner_sid = offset_sid; - if (dst->owner_sid != NULL) + dst->off_owner_sid = offset_sid; + + /* sid_size() returns 0 if the sid is NULL so this is ok */ + + if (dst->grp_sid != NULL) dst->off_grp_sid = offset_sid + sid_size(dst->owner_sid); - else - dst->off_grp_sid = offset_sid; return dst; @@ -748,8 +747,15 @@ BOOL sec_io_desc(char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth) prs_debug(ps, depth, desc, "sec_io_desc"); depth++; +#if 0 + /* + * if alignment is needed, should be done by the the + * caller. Not here. This caused me problems when marshalling + * printer info into a buffer. --jerry + */ if(!prs_align(ps)) return False; +#endif /* start of security descriptor stored for back-calc offset purposes */ old_offset = prs_offset(ps); @@ -776,72 +782,69 @@ BOOL sec_io_desc(char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth) if (psd->off_owner_sid != 0) { + tmp_offset = ps->data_offset; + if(!prs_set_offset(ps, old_offset + psd->off_owner_sid)) + return False; + if (UNMARSHALLING(ps)) { - if(!prs_set_offset(ps, old_offset + psd->off_owner_sid)) - return False; /* reading */ if((psd->owner_sid = (DOM_SID *)prs_alloc_mem(ps,sizeof(*psd->owner_sid))) == NULL) return False; } - tmp_offset = ps->data_offset; - ps->data_offset = psd->off_owner_sid; - if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth)) return False; - if(!prs_align(ps)) - return False; - ps->data_offset = tmp_offset; - } + max_offset = MAX(max_offset, prs_offset(ps)); - max_offset = MAX(max_offset, prs_offset(ps)); + if (!prs_set_offset(ps,tmp_offset)) + return False; + } if (psd->off_grp_sid != 0) { + tmp_offset = ps->data_offset; + if(!prs_set_offset(ps, old_offset + psd->off_grp_sid)) + return False; + if (UNMARSHALLING(ps)) { /* reading */ - if(!prs_set_offset(ps, old_offset + psd->off_grp_sid)) - return False; if((psd->grp_sid = (DOM_SID *)prs_alloc_mem(ps,sizeof(*psd->grp_sid))) == NULL) return False; } - tmp_offset = ps->data_offset; - ps->data_offset = psd->off_grp_sid; - if(!smb_io_dom_sid("grp_sid", psd->grp_sid, ps, depth)) return False; - if(!prs_align(ps)) - return False; + + max_offset = MAX(max_offset, prs_offset(ps)); - ps->data_offset = tmp_offset; + if (!prs_set_offset(ps,tmp_offset)) + return False; } - max_offset = MAX(max_offset, prs_offset(ps)); - if ((psd->type & SEC_DESC_SACL_PRESENT) && psd->off_sacl) { + tmp_offset = ps->data_offset; if(!prs_set_offset(ps, old_offset + psd->off_sacl)) return False; if(!sec_io_acl("sacl", &psd->sacl, ps, depth)) return False; - if(!prs_align(ps)) + max_offset = MAX(max_offset, prs_offset(ps)); + if (!prs_set_offset(ps,tmp_offset)) return False; } - max_offset = MAX(max_offset, prs_offset(ps)); if ((psd->type & SEC_DESC_DACL_PRESENT) && psd->off_dacl != 0) { + tmp_offset = ps->data_offset; if(!prs_set_offset(ps, old_offset + psd->off_dacl)) return False; if(!sec_io_acl("dacl", &psd->dacl, ps, depth)) return False; - if(!prs_align(ps)) + max_offset = MAX(max_offset, prs_offset(ps)); + if (!prs_set_offset(ps,tmp_offset)) return False; } - max_offset = MAX(max_offset, prs_offset(ps)); - if(!prs_set_offset(ps, max_offset)) return False; return True; diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index e9f0ca858a..b10a5c4377 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -4,8 +4,8 @@ * Copyright (C) Andrew Tridgell 1992-2000, * Copyright (C) Luke Kenneth Casson Leighton 1996-2000, * Copyright (C) Jean François Micouleau 1998-2000, - * Copyright (C) Gerald Carter 2000-2002 - * Copyright (C) Tim Potter 2001. + * Copyright (C) Gerald Carter 2000-2002, + * Copyright (C) Tim Potter 2001-2002. * * 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 @@ -24,6 +24,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_PARSE + /******************************************************************* return the length of a UNISTR string. ********************************************************************/ @@ -45,7 +48,7 @@ static uint32 str_len_uni(UNISTR *source) This should be moved in a more generic lib. ********************************************************************/ -static BOOL spoolss_io_system_time(char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime) +BOOL spoolss_io_system_time(char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime) { if(!prs_uint16("year", ps, depth, &systime->year)) return False; @@ -321,53 +324,64 @@ static BOOL smb_io_notify_info_data(char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs { uint32 useless_ptr=0xADDE0FF0; - uint32 how_many_words; - BOOL isvalue; - uint32 x; - prs_debug(ps, depth, desc, "smb_io_notify_info_data"); depth++; - how_many_words=data->size; - if (how_many_words==POINTER) { - how_many_words=TWO_VALUE; - } - - isvalue=data->enc_type; - if(!prs_align(ps)) return False; if(!prs_uint16("type", ps, depth, &data->type)) return False; if(!prs_uint16("field", ps, depth, &data->field)) return False; - /*prs_align(ps);*/ - if(!prs_uint32("how many words", ps, depth, &how_many_words)) + if(!prs_uint32("how many words", ps, depth, &data->size)) return False; if(!prs_uint32("id", ps, depth, &data->id)) return False; - if(!prs_uint32("how many words", ps, depth, &how_many_words)) + if(!prs_uint32("how many words", ps, depth, &data->size)) return False; + switch (data->enc_type) { + + /* One and two value data has two uint32 values */ - /*prs_align(ps);*/ + case NOTIFY_ONE_VALUE: + case NOTIFY_TWO_VALUE: - if (isvalue==True) { if(!prs_uint32("value[0]", ps, depth, &data->notify_data.value[0])) return False; if(!prs_uint32("value[1]", ps, depth, &data->notify_data.value[1])) return False; - /*prs_align(ps);*/ - } else { - /* it's a string */ - /* length in ascii including \0 */ - x=2*(data->notify_data.data.length+1); - if(!prs_uint32("string length", ps, depth, &x )) + break; + + /* Pointers and strings have a string length and a + pointer. For a string the length is expressed as + the number of uint16 characters plus a trailing + \0\0. */ + + case NOTIFY_POINTER: + + if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length )) return False; if(!prs_uint32("pointer", ps, depth, &useless_ptr)) return False; - /*prs_align(ps);*/ + + break; + + case NOTIFY_STRING: + + if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length)) + return False; + + if(!prs_uint32("pointer", ps, depth, &useless_ptr)) + return False; + + break; + + default: + DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data\n", + data->enc_type)); + break; } return True; @@ -380,22 +394,79 @@ reads or writes an NOTIFY INFO DATA structure. BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs_struct *ps, int depth) { - uint32 x; - BOOL isvalue; - prs_debug(ps, depth, desc, "smb_io_notify_info_data_strings"); depth++; if(!prs_align(ps)) return False; - isvalue=data->enc_type; + switch(data->enc_type) { + + /* No data for values */ + + case NOTIFY_ONE_VALUE: + case NOTIFY_TWO_VALUE: + + break; + + /* Strings start with a length in uint16s */ + + case NOTIFY_STRING: + + if (UNMARSHALLING(ps)) { + data->notify_data.data.string = + (uint16 *)prs_alloc_mem(ps, data->notify_data.data.length); + + if (!data->notify_data.data.string) + return False; + } + + if (MARSHALLING(ps)) + data->notify_data.data.length /= 2; + + if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length)) + return False; + + if (!prs_uint16uni(True, "string", ps, depth, data->notify_data.data.string, + data->notify_data.data.length)) + return False; + + if (MARSHALLING(ps)) + data->notify_data.data.length *= 2; + + break; + + case NOTIFY_POINTER: + + if (UNMARSHALLING(ps)) { + data->notify_data.data.string = + (uint16 *)prs_alloc_mem(ps, data->notify_data.data.length); + + if (!data->notify_data.data.string) + return False; + } + + if(!prs_uint8s(True,"buffer",ps,depth,(uint8*)data->notify_data.data.string,data->notify_data.data.length)) + return False; + + break; + + default: + DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data_strings\n", + data->enc_type)); + break; + } +#if 0 if (isvalue==False) { + /* length of string in unicode include \0 */ x=data->notify_data.data.length+1; + + if (data->field != 16) if(!prs_uint32("string length", ps, depth, &x )) return False; + if (MARSHALLING(ps)) { /* These are already in little endian format. Don't byte swap. */ if (x == 1) { @@ -409,6 +480,10 @@ BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data, if(!prs_uint8s(True,"string",ps,depth, (uint8 *)&data->notify_data.data.length,x*2)) return False; } else { + + if (data->field == 16) + x /= 2; + if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x)) return False; } @@ -424,10 +499,11 @@ BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data, return False; } } -#if 0 /* JERRY */ - /* Win2k does not seem to put this parse align here */ +#endif +#if 0 /* JERRY */ + /* Win2k does not seem to put this parse align here */ if(!prs_align(ps)) return False; #endif @@ -546,8 +622,40 @@ static BOOL spool_io_user_level(char *desc, SPOOL_USER_CTR *q_u, prs_struct *ps, * on reading allocate memory for the private member ********************************************************************/ +#define DM_NUM_OPTIONAL_FIELDS 8 + BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode) { + uint32 available_space; /* size of the device mode left to parse */ + /* only important on unmarshalling */ + int i = 0; + + struct optional_fields { + fstring name; + uint32* field; + } opt_fields[DM_NUM_OPTIONAL_FIELDS] = { + { "icmmethod", NULL }, + { "icmintent", NULL }, + { "mediatype", NULL }, + { "dithertype", NULL }, + { "reserved1", NULL }, + { "reserved2", NULL }, + { "panningwidth", NULL }, + { "panningheight", NULL } + }; + + /* assign at run time to keep non-gcc vompilers happy */ + + opt_fields[0].field = &devmode->icmmethod; + opt_fields[1].field = &devmode->icmintent; + opt_fields[2].field = &devmode->mediatype; + opt_fields[3].field = &devmode->dithertype; + opt_fields[4].field = &devmode->reserved1; + opt_fields[5].field = &devmode->reserved2; + opt_fields[6].field = &devmode->panningwidth; + opt_fields[7].field = &devmode->panningheight; + + prs_debug(ps, depth, desc, "spoolss_io_devmode"); depth++; @@ -559,8 +667,27 @@ BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmo if (!prs_uint16uni(True,"devicename", ps, depth, devmode->devicename.buffer, 32)) return False; + if (!prs_uint16("specversion", ps, depth, &devmode->specversion)) return False; + + /* Sanity Check - look for unknown specversions, but don't fail if we see one. + Let the size determine that */ + + switch (devmode->specversion) { + case 0x0320: + case 0x0400: + case 0x0401: + break; + + default: + DEBUG(0,("spoolss_io_devmode: Unknown specversion in devicemode [0x%x]\n", + devmode->specversion)); + DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n")); + break; + } + + if (!prs_uint16("driverversion", ps, depth, &devmode->driverversion)) return False; if (!prs_uint16("size", ps, depth, &devmode->size)) @@ -616,45 +743,50 @@ BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmo return False; if (!prs_uint32("displayfrequency", ps, depth, &devmode->displayfrequency)) return False; + /* + * every device mode I've ever seen on the wire at least has up + * to the displayfrequency field. --jerry (05-09-2002) + */ + + /* add uint32's + uint16's + two UNICODE strings */ + + available_space = devmode->size - (sizeof(uint32)*6 + sizeof(uint16)*18 + sizeof(uint16)*64); + + /* Sanity check - we only have uint32's left tp parse */ + + if ( available_space && ((available_space % sizeof(uint32)) != 0) ) { + DEBUG(0,("spoolss_io_devmode: available_space [%d] no in multiple of 4 bytes (size = %d)!\n", + available_space, devmode->size)); + DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n")); + return False; + } /* * Conditional parsing. Assume that the DeviceMode has been * zero'd by the caller. */ - switch(devmode->specversion) { - /* Used by spooler when issuing OpenPrinter() calls. NT 3.5x? */ - case 0x0320: - break; + while ((available_space > 0) && (i < DM_NUM_OPTIONAL_FIELDS)) + { + DEBUG(10, ("spoolss_io_devmode: [%d] bytes left to parse in devmode\n", available_space)); + if (!prs_uint32(opt_fields[i].name, ps, depth, opt_fields[i].field)) + return False; + available_space -= sizeof(uint32); + i++; + } + + /* Sanity Check - we should no available space at this point unless + MS changes the device mode structure */ - /* See the comments on the DEVMODE in the msdn GDI documentation */ - case 0x0400: - case 0x0401: - if (!prs_uint32("icmmethod", ps, depth, &devmode->icmmethod)) - return False; - if (!prs_uint32("icmintent", ps, depth, &devmode->icmintent)) - return False; - if (!prs_uint32("mediatype", ps, depth, &devmode->mediatype)) - return False; - if (!prs_uint32("dithertype", ps, depth, &devmode->dithertype)) - return False; - if (!prs_uint32("reserved1", ps, depth, &devmode->reserved1)) - return False; - if (!prs_uint32("reserved2", ps, depth, &devmode->reserved2)) + if (available_space) { + DEBUG(0,("spoolss_io_devmode: I've parsed all I know and there is still stuff left|\n")); + DEBUG(0,("spoolss_io_devmode: available_space = [%d], devmode_size = [%d]!\n", + available_space, devmode->size)); + DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n")); return False; - if (!prs_uint32("panningwidth", ps, depth, &devmode->panningwidth)) - return False; - if (!prs_uint32("panningheight", ps, depth, &devmode->panningheight)) - return False; - break; - - /* log an error if we see something else */ - default: - DEBUG(0,("spoolss_io_devmode: Unknown specversion [0x%x]!\n", devmode->specversion)); - DEBUG(0,("spoolss_io_devmode: Please report to samba-technical@samba.org\n")); - break; } + if (devmode->driverextra!=0) { if (UNMARSHALLING(ps)) { devmode->private=(uint8 *)prs_alloc_mem(ps, devmode->driverextra*sizeof(uint8)); @@ -900,6 +1032,7 @@ BOOL make_spoolss_printer_info_2(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_2 return True; } + /******************************************************************* * read a structure. * called from spoolss_q_open_printer_ex (srv_spoolss.c) @@ -1047,15 +1180,15 @@ BOOL make_spoolss_q_deleteprinterdriver( ********************************************************************/ BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u, - const POLICY_HND *handle, - UNISTR2 *valuename, uint32 size) + const POLICY_HND *handle, + char *valuename, uint32 size) { if (q_u == NULL) return False; DEBUG(5,("make_spoolss_q_getprinterdata\n")); q_u->handle = *handle; - copy_unistr2(&q_u->valuename, valuename); + init_unistr2(&q_u->valuename, valuename, strlen(valuename) + 1); q_u->size = size; return True; @@ -1130,6 +1263,48 @@ BOOL spoolss_io_r_deleteprinterdata(char *desc, SPOOL_R_DELETEPRINTERDATA *r_u, return True; } +/******************************************************************* + * read a structure. + * called from spoolss_q_deleteprinterdataex (srv_spoolss.c) + ********************************************************************/ + +BOOL spoolss_io_q_deleteprinterdataex(char *desc, SPOOL_Q_DELETEPRINTERDATAEX *q_u, prs_struct *ps, int depth) +{ + if (q_u == NULL) + return False; + + prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdataex"); + depth++; + + if (!prs_align(ps)) + return False; + if (!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth)) + return False; + + if (!smb_io_unistr2("keyname ", &q_u->keyname, True, ps, depth)) + return False; + if (!smb_io_unistr2("valuename", &q_u->valuename, True, ps, depth)) + return False; + + return True; +} + +/******************************************************************* + * write a structure. + * called from spoolss_r_deleteprinterdataex (srv_spoolss.c) + ********************************************************************/ + +BOOL spoolss_io_r_deleteprinterdataex(char *desc, SPOOL_R_DELETEPRINTERDATAEX *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdataex"); + depth++; + + if(!prs_werror("status", ps, depth, &r_u->status)) + return False; + + return True; +} + /******************************************************************* * write a structure. * called from spoolss_r_getprinterdata (srv_spoolss.c) @@ -1150,6 +1325,12 @@ BOOL spoolss_io_r_getprinterdata(char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_st if (!prs_uint32("size", ps, depth, &r_u->size)) return False; + if (UNMARSHALLING(ps) && r_u->size) { + r_u->data = prs_alloc_mem(ps, r_u->size); + if(r_u->data) + return False; + } + if (!prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size)) return False; @@ -1311,6 +1492,64 @@ BOOL spoolss_io_r_deleteprinterdriver(char *desc, SPOOL_R_DELETEPRINTERDRIVER *r } +/******************************************************************* + * read a structure. + * called from api_spoolss_deleteprinterdriver (srv_spoolss.c) + * called from spoolss_deleteprinterdriver (cli_spoolss.c) + ********************************************************************/ + +BOOL spoolss_io_q_deleteprinterdriverex(char *desc, SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, prs_struct *ps, int depth) +{ + if (q_u == NULL) return False; + + prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdriverex"); + depth++; + + if (!prs_align(ps)) + return False; + + if(!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr)) + return False; + if(!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth)) + return False; + if(!smb_io_unistr2("arch", &q_u->arch, True, ps, depth)) + return False; + if(!smb_io_unistr2("driver", &q_u->driver, True, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + + if(!prs_uint32("delete_flags ", ps, depth, &q_u->delete_flags)) + return False; + if(!prs_uint32("version ", ps, depth, &q_u->version)) + return False; + + + return True; +} + + +/******************************************************************* + * write a structure. + ********************************************************************/ +BOOL spoolss_io_r_deleteprinterdriverex(char *desc, SPOOL_R_DELETEPRINTERDRIVEREX *r_u, prs_struct *ps, int depth) +{ + if (r_u == NULL) return False; + + prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdriverex"); + depth++; + + if (!prs_align(ps)) + return False; + + if (!prs_werror("status", ps, depth, &r_u->status)) + return False; + + return True; +} + + /******************************************************************* * read a structure. @@ -2072,6 +2311,10 @@ static BOOL smb_io_reldevmode(char *desc, NEW_BUFFER *buffer, int depth, DEVICEM /* read the offset */ if (!prs_uint32("offset", ps, depth, &buffer->string_at_end)) return False; + if (buffer->string_at_end == 0) { + *devmode = NULL; + return True; + } old_offset = prs_offset(ps); if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start)) @@ -2222,6 +2465,8 @@ BOOL smb_io_printer_info_1(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 *info, BOOL smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, int depth) { prs_struct *ps=&buffer->prs; + uint32 dm_offset, sd_offset, current_offset; + uint32 dummy_value = 0; prs_debug(ps, depth, desc, "smb_io_printer_info_2"); depth++; @@ -2243,8 +2488,9 @@ BOOL smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, if (!smb_io_relstr("location", buffer, depth, &info->location)) return False; - /* NT parses the DEVMODE at the end of the struct */ - if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode)) + /* save current offset and wind forwared by a uint32 */ + dm_offset = prs_offset(ps); + if (!prs_uint32("devmode", ps, depth, &dummy_value)) return False; if (!smb_io_relstr("sepfile", buffer, depth, &info->sepfile)) @@ -2256,9 +2502,31 @@ BOOL smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, if (!smb_io_relstr("parameters", buffer, depth, &info->parameters)) return False; + /* save current offset for the sec_desc */ + sd_offset = prs_offset(ps); + if (!prs_uint32("sec_desc", ps, depth, &dummy_value)) + return False; + + + /* save current location so we can pick back up here */ + current_offset = prs_offset(ps); + + /* parse the devmode */ + if (!prs_set_offset(ps, dm_offset)) + return False; + if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode)) + return False; + + /* parse the sec_desc */ + if (!prs_set_offset(ps, sd_offset)) + return False; if (!smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc)) return False; + /* pick up where we left off */ + if (!prs_set_offset(ps, current_offset)) + return False; + if (!prs_uint32("attributes", ps, depth, &info->attributes)) return False; if (!prs_uint32("priority", ps, depth, &info->priority)) @@ -2276,13 +2544,6 @@ BOOL smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, if (!prs_uint32("averageppm", ps, depth, &info->averageppm)) return False; -#if 0 /* JFMTEST */ - if (!prs_uint32_post("secdesc_ptr", ps, depth, NULL, sec_offset, info->secdesc ? prs_offset(ps)-buffer->struct_start : 0 )) - return False; - - if (!sec_io_desc("secdesc", &info->secdesc, ps, depth)) - return False; -#endif return True; } @@ -3034,7 +3295,7 @@ uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info) uint32 size=0; size += 4; - /* JRA !!!! TESTME - WHAT ABOUT prs_align.... !!! */ + size += sec_desc_size( info->secdesc ); size+=size_of_device_mode( info->devmode ); @@ -3060,6 +3321,16 @@ uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info) size+=size_of_uint32( &info->status ); size+=size_of_uint32( &info->cjobs ); size+=size_of_uint32( &info->averageppm ); + + /* + * add any adjustments for alignment. This is + * not optimal since we could be calling this + * function from a loop (e.g. enumprinters), but + * it is easier to maintain the calculation here and + * not place the burden on the caller to remember. --jerry + */ + size += size % 4; + return size; } @@ -3529,7 +3800,7 @@ BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, BOOL make_spoolss_q_enumprinters( SPOOL_Q_ENUMPRINTERS *q_u, uint32 flags, - fstring servername, + char *servername, uint32 level, NEW_BUFFER *buffer, uint32 offered @@ -4767,60 +5038,56 @@ BOOL spool_io_printer_driver_info_level_6(char *desc, SPOOL_PRINTER_DRIVER_INFO_ if(!prs_align(ps)) return False; + /* + * I know this seems weird, but I have no other explanation. + * This is observed behavior on both NT4 and 2K servers. + * --jerry + */ + + if (!prs_align_uint64(ps)) + return False; /* parse the main elements the packet */ - if(!prs_uint32("version", ps, depth, &il->version)) + if(!prs_uint32("cversion ", ps, depth, &il->version)) return False; - - if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr)) - return False; - /* - * If name_ptr is NULL then the next 4 bytes are the name_ptr. A driver - * with a NULL name just isn't a driver For example: "HP LaserJet 4si" - * from W2K CDROM (which uses unidriver). JohnR 010205 - */ - if (!il->name_ptr) { - DEBUG(5,("spool_io_printer_driver_info_level_6: name_ptr is NULL! Get next value\n")); - if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr)) - return False; - } - - if(!prs_uint32("environment_ptr", ps, depth, &il->environment_ptr)) + if(!prs_uint32("name ", ps, depth, &il->name_ptr)) return False; - if(!prs_uint32("driverpath_ptr", ps, depth, &il->driverpath_ptr)) + if(!prs_uint32("environment ", ps, depth, &il->environment_ptr)) return False; - if(!prs_uint32("datafile_ptr", ps, depth, &il->datafile_ptr)) + if(!prs_uint32("driverpath ", ps, depth, &il->driverpath_ptr)) return False; - if(!prs_uint32("configfile_ptr", ps, depth, &il->configfile_ptr)) + if(!prs_uint32("datafile ", ps, depth, &il->datafile_ptr)) return False; - if(!prs_uint32("helpfile_ptr", ps, depth, &il->helpfile_ptr)) + if(!prs_uint32("configfile ", ps, depth, &il->configfile_ptr)) return False; - if(!prs_uint32("monitorname_ptr", ps, depth, &il->monitorname_ptr)) + if(!prs_uint32("helpfile ", ps, depth, &il->helpfile_ptr)) return False; - if(!prs_uint32("defaultdatatype_ptr", ps, depth, &il->defaultdatatype_ptr)) + if(!prs_uint32("monitorname ", ps, depth, &il->monitorname_ptr)) return False; - if(!prs_uint32("dependentfiles_len", ps, depth, &il->dependentfiles_len)) + if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr)) return False; - if(!prs_uint32("dependentfiles_ptr", ps, depth, &il->dependentfiles_ptr)) + if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_len)) return False; - if(!prs_uint32("previousnames_len", ps, depth, &il->previousnames_len)) + if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_ptr)) return False; - if(!prs_uint32("previousnames_ptr", ps, depth, &il->previousnames_ptr)) + if(!prs_uint32("previousnames ", ps, depth, &il->previousnames_len)) return False; - if(!smb_io_time("driverdate", &il->driverdate, ps, depth)) + if(!prs_uint32("previousnames ", ps, depth, &il->previousnames_ptr)) return False; - if(!prs_uint32("dummy4", ps, depth, &il->dummy4)) + if(!smb_io_time("driverdate ", &il->driverdate, ps, depth)) return False; - if(!prs_uint64("driverversion", ps, depth, &il->driverversion)) + if(!prs_uint32("dummy4 ", ps, depth, &il->dummy4)) return False; - if(!prs_uint32("mfgname_ptr", ps, depth, &il->mfgname_ptr)) + if(!prs_uint64("driverversion ", ps, depth, &il->driverversion)) return False; - if(!prs_uint32("oemurl_ptr", ps, depth, &il->oemurl_ptr)) + if(!prs_uint32("mfgname ", ps, depth, &il->mfgname_ptr)) return False; - if(!prs_uint32("hardwareid_ptr", ps, depth, &il->hardwareid_ptr)) + if(!prs_uint32("oemurl ", ps, depth, &il->oemurl_ptr)) return False; - if(!prs_uint32("provider_ptr", ps, depth, &il->provider_ptr)) + if(!prs_uint32("hardwareid ", ps, depth, &il->hardwareid_ptr)) + return False; + if(!prs_uint32("provider ", ps, depth, &il->provider_ptr)) return False; /* parse the structures in the packet */ @@ -5146,6 +5413,53 @@ BOOL spoolss_io_r_addprinterdriver(char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, pr return True; } +/******************************************************************* + fill in the prs_struct for a ADDPRINTERDRIVER request PDU + ********************************************************************/ + +BOOL spoolss_io_q_addprinterdriverex(char *desc, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriverex"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr)) + return False; + if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; + if(!prs_uint32("info_level", ps, depth, &q_u->level)) + return False; + + if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; + if(!prs_uint32("copy flags", ps, depth, &q_u->copy_flags)) + return False; + + return True; +} + +/******************************************************************* +********************************************************************/ + +BOOL spoolss_io_r_addprinterdriverex(char *desc, SPOOL_R_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriverex"); + depth++; + + if(!prs_werror("status", ps, depth, &q_u->status)) + return False; + + return True; +} + /******************************************************************* ********************************************************************/ @@ -5653,6 +5967,14 @@ BOOL spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_ if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize)) return False; + if (UNMARSHALLING(ps) && r_u->valuesize) { + r_u->value = (uint16 *)prs_alloc_mem(ps, r_u->valuesize * 2); + if (!r_u->value) { + DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata value\n")); + return False; + } + } + if(!prs_uint16uni(False, "value", ps, depth, r_u->value, r_u->valuesize )) return False; @@ -5667,6 +5989,15 @@ BOOL spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_ if(!prs_uint32("datasize", ps, depth, &r_u->datasize)) return False; + + if (UNMARSHALLING(ps) && r_u->datasize) { + r_u->data = (uint8 *)prs_alloc_mem(ps, r_u->datasize); + if (!r_u->data) { + DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata data\n")); + return False; + } + } + if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize)) return False; if(!prs_align(ps)) @@ -5719,19 +6050,15 @@ BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u, /******************************************************************* ********************************************************************/ -BOOL make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, TALLOC_CTX *ctx, const POLICY_HND *hnd, - char* value, char* data) +BOOL make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd, + char* value, char* data, uint32 data_size) { - UNISTR2 tmp; - memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); q_u->type = REG_SZ; init_unistr2(&q_u->value, value, strlen(value)+1); - init_unistr2(&tmp, data, strlen(data)+1); - q_u->max_len = q_u->real_len = tmp.uni_max_len*2; - q_u->data = talloc(ctx, q_u->real_len); - memcpy(q_u->data, tmp.buffer, q_u->real_len); + q_u->max_len = q_u->real_len = data_size; + q_u->data = data; return True; } @@ -6696,6 +7023,44 @@ BOOL spoolss_io_r_enumprinterkey(char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_st return True; } +/******************************************************************* + * read a structure. + ********************************************************************/ + +BOOL spoolss_io_q_deleteprinterkey(char *desc, SPOOL_Q_DELETEPRINTERKEY *q_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterkey"); + depth++; + + if(!prs_align(ps)) + return False; + if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth)) + return False; + + if(!smb_io_unistr2("", &q_u->keyname, True, ps, depth)) + return False; + + return True; +} + +/******************************************************************* + * write a structure. + ********************************************************************/ + +BOOL spoolss_io_r_deleteprinterkey(char *desc, SPOOL_R_DELETEPRINTERKEY *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterkey"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_werror("status", ps, depth, &r_u->status)) + return False; + + return True; +} + /******************************************************************* * read a structure. @@ -7016,3 +7381,150 @@ BOOL make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, return True; } + +/******************************************************************* + * init a structure. + ********************************************************************/ + +BOOL make_spoolss_q_setjob(SPOOL_Q_SETJOB *q_u, POLICY_HND *handle, + uint32 jobid, uint32 level, uint32 command) +{ + memcpy(&q_u->handle, handle, sizeof(POLICY_HND)); + q_u->jobid = jobid; + q_u->level = level; + + /* Hmm - the SPOOL_Q_SETJOB structure has a JOB_INFO ctr in it but + the server side code has it marked as unused. */ + + q_u->command = command; + + return True; +} + +/******************************************************************* + * init a structure. + ********************************************************************/ + +BOOL make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle, + uint32 jobid, uint32 level, NEW_BUFFER *buffer, + uint32 offered) +{ + memcpy(&q_u->handle, handle, sizeof(POLICY_HND)); + q_u->jobid = jobid; + q_u->level = level; + q_u->buffer = buffer; + q_u->offered = offered; + + return True; +} + +/******************************************************************* + * init a structure. + ********************************************************************/ + +BOOL make_spoolss_q_startpageprinter(SPOOL_Q_STARTPAGEPRINTER *q_u, + POLICY_HND *handle) +{ + memcpy(&q_u->handle, handle, sizeof(POLICY_HND)); + + return True; +} + +/******************************************************************* + * init a structure. + ********************************************************************/ + +BOOL make_spoolss_q_endpageprinter(SPOOL_Q_ENDPAGEPRINTER *q_u, + POLICY_HND *handle) +{ + memcpy(&q_u->handle, handle, sizeof(POLICY_HND)); + + return True; +} + +/******************************************************************* + * init a structure. + ********************************************************************/ + +BOOL make_spoolss_q_startdocprinter(SPOOL_Q_STARTDOCPRINTER *q_u, + POLICY_HND *handle, uint32 level, + char *docname, char *outputfile, + char *datatype) +{ + DOC_INFO_CONTAINER *ctr = &q_u->doc_info_container; + + memcpy(&q_u->handle, handle, sizeof(POLICY_HND)); + + ctr->level = level; + + switch (level) { + case 1: + ctr->docinfo.switch_value = level; + + ctr->docinfo.doc_info_1.p_docname = docname ? 1 : 0; + ctr->docinfo.doc_info_1.p_outputfile = outputfile ? 1 : 0; + ctr->docinfo.doc_info_1.p_datatype = datatype ? 1 : 0; + + if (docname) + init_unistr2(&ctr->docinfo.doc_info_1.docname, docname, + strlen(docname) + 1); + + if (outputfile) + init_unistr2(&ctr->docinfo.doc_info_1.outputfile, outputfile, + strlen(outputfile) + 1); + + if (datatype) + init_unistr2(&ctr->docinfo.doc_info_1.datatype, datatype, + strlen(datatype) + 1); + + break; + case 2: + /* DOC_INFO_2 is only used by Windows 9x and since it + doesn't do printing over RPC we don't have to worry + about it. */ + default: + DEBUG(3, ("unsupported info level %d\n", level)); + return False; + } + + return True; +} + +/******************************************************************* + * init a structure. + ********************************************************************/ + +BOOL make_spoolss_q_enddocprinter(SPOOL_Q_ENDDOCPRINTER *q_u, + POLICY_HND *handle) +{ + memcpy(&q_u->handle, handle, sizeof(POLICY_HND)); + + return True; +} + +/******************************************************************* + * init a structure. + ********************************************************************/ + +BOOL make_spoolss_q_writeprinter(SPOOL_Q_WRITEPRINTER *q_u, + POLICY_HND *handle, uint32 data_size, + char *data) +{ + memcpy(&q_u->handle, handle, sizeof(POLICY_HND)); + q_u->buffer_size = q_u->buffer_size2 = data_size; + q_u->buffer = data; + return True; +} + +/******************************************************************* + * init a structure. + ********************************************************************/ + +BOOL make_spoolss_q_deleteprinterdata(SPOOL_Q_DELETEPRINTERDATA *q_u, + POLICY_HND *handle, char *valuename) +{ + memcpy(&q_u->handle, handle, sizeof(POLICY_HND)); + init_unistr2(&q_u->valuename, valuename, strlen(valuename) + 1); + + return True; +} diff --git a/source3/rpc_parse/parse_srv.c b/source3/rpc_parse/parse_srv.c index 9c9d5f1e9c..3dc054d2b1 100644 --- a/source3/rpc_parse/parse_srv.c +++ b/source3/rpc_parse/parse_srv.c @@ -5,6 +5,7 @@ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, * Copyright (C) Paul Ashton 1997. * Copyright (C) Jeremy Allison 1999. + * Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2002 * * 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 @@ -23,6 +24,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_PARSE + /******************************************************************* Inits a SH_INFO_1_STR structure ********************************************************************/ @@ -108,10 +112,14 @@ void init_srv_share_info2_str(SH_INFO_2_STR *sh2, { DEBUG(5,("init_srv_share_info2_str\n")); - init_unistr2(&sh2->uni_netname, net_name, strlen(net_name)+1); - init_unistr2(&sh2->uni_remark, remark, strlen(remark)+1); - init_unistr2(&sh2->uni_path, path, strlen(path)+1); - init_unistr2(&sh2->uni_passwd, passwd, strlen(passwd)+1); + if (net_name) + init_unistr2(&sh2->uni_netname, net_name, strlen(net_name)+1); + if (remark) + init_unistr2(&sh2->uni_remark, remark, strlen(remark)+1); + if (path) + init_unistr2(&sh2->uni_path, path, strlen(path)+1); + if (passwd) + init_unistr2(&sh2->uni_passwd, passwd, strlen(passwd)+1); } /******************************************************************* @@ -658,7 +666,9 @@ void init_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n, init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name); q_n->ctr.info_level = q_n->ctr.switch_value = info_level; - q_n->ctr.ptr_share_info = 0; + q_n->ctr.ptr_share_info = 1; + q_n->ctr.num_entries = 0; + q_n->ctr.ptr_entries = 0; q_n->preferred_len = preferred_len; memcpy(&q_n->enum_hnd, hnd, sizeof(*hnd)); @@ -952,9 +962,34 @@ BOOL srv_io_q_net_share_add(char *desc, SRV_Q_NET_SHARE_ADD *q_n, prs_struct *ps if(!srv_io_srv_share_info("info ", ps, depth, &q_n->info)) return False; + if(!prs_uint32("ptr_err_index", ps, depth, &q_n->ptr_err_index)) + return False; + if (q_n->ptr_err_index) + if (!prs_uint32("err_index", ps, depth, &q_n->err_index)) + return False; + return True; } +void init_srv_q_net_share_add(SRV_Q_NET_SHARE_ADD *q, char *srvname, + char *netname, uint32 type, char *remark, + uint32 perms, uint32 max_uses, uint32 num_uses, + char *path, char *passwd) +{ + q->ptr_srv_name = 1; + init_unistr2(&q->uni_srv_name, srvname, strlen(srvname) +1); + q->info.switch_value = q->info_level = 2; + + q->info.ptr_share_ctr = 1; + init_srv_share_info2(&q->info.share.info2.info_2, netname, type, + remark, perms, max_uses, num_uses, path, passwd); + init_srv_share_info2_str(&q->info.share.info2.info_2_str, netname, + remark, path, passwd); + q->ptr_err_index = 1; + q->err_index = 0; +} + + /******************************************************************* Reads or writes a structure. ********************************************************************/ @@ -978,6 +1013,14 @@ BOOL srv_io_r_net_share_add(char *desc, SRV_R_NET_SHARE_ADD *q_n, prs_struct *ps return True; } +void init_srv_q_net_share_del(SRV_Q_NET_SHARE_DEL *del, const char *srvname, + const char *sharename) +{ + del->ptr_srv_name = 1; + init_unistr2(&del->uni_srv_name, srvname, strlen(srvname) +1 ); + init_unistr2(&del->uni_share_name, sharename, strlen(sharename) + 1); +} + /******************************************************************* Reads or writes a structure. ********************************************************************/ @@ -1001,6 +1044,11 @@ BOOL srv_io_q_net_share_del(char *desc, SRV_Q_NET_SHARE_DEL *q_n, prs_struct *ps if(!smb_io_unistr2("", &q_n->uni_share_name, True, ps, depth)) return False; + if(!prs_align(ps)) + return False; + if(!prs_uint32("reserved", ps, depth, &q_n->reserved)) + return False; + return True; } @@ -1148,7 +1196,7 @@ void init_srv_sess_info1_str(SESS_INFO_1_STR *ss1, char *name, char *user) DEBUG(5,("init_srv_sess_info1_str\n")); init_unistr2(&ss1->uni_name, name, strlen(name)+1); - init_unistr2(&ss1->uni_user, name, strlen(user)+1); + init_unistr2(&ss1->uni_user, user, strlen(user)+1); } /******************************************************************* @@ -1329,10 +1377,10 @@ static BOOL srv_io_srv_sess_ctr(char *desc, SRV_SESS_INFO_CTR **pp_ctr, prs_stru ********************************************************************/ void init_srv_q_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n, - char *srv_name, char *qual_name, - uint32 sess_level, SRV_SESS_INFO_CTR *ctr, - uint32 preferred_len, - ENUM_HND *hnd) + char *srv_name, char *qual_name, + char *user_name, uint32 sess_level, + SRV_SESS_INFO_CTR *ctr, uint32 preferred_len, + ENUM_HND *hnd) { q_n->ctr = ctr; @@ -1340,6 +1388,7 @@ void init_srv_q_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n, init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name); init_buf_unistr2(&q_n->uni_qual_name, &q_n->ptr_qual_name, qual_name); + init_buf_unistr2(&q_n->uni_user_name, &q_n->ptr_user_name, user_name); q_n->sess_level = sess_level; q_n->preferred_len = preferred_len; @@ -1375,6 +1424,13 @@ BOOL srv_io_q_net_sess_enum(char *desc, SRV_Q_NET_SESS_ENUM *q_n, prs_struct *ps if(!smb_io_unistr2("", &q_n->uni_qual_name, q_n->ptr_qual_name, ps, depth)) return False; + if(!prs_align(ps)) + return False; + if(!prs_uint32("ptr_user_name", ps, depth, &q_n->ptr_user_name)) + return False; + if(!smb_io_unistr2("", &q_n->uni_user_name, q_n->ptr_user_name, ps, depth)) + return False; + if(!prs_align(ps)) return False; @@ -1879,91 +1935,67 @@ static BOOL srv_io_file_info3(char *desc, FILE_INFO_3 *fl3, prs_struct *ps, int Reads or writes a structure. ********************************************************************/ -static BOOL srv_io_srv_file_info_3(char *desc, SRV_FILE_INFO_3 *fl3, prs_struct *ps, int depth) +static BOOL srv_io_srv_file_ctr(char *desc, SRV_FILE_INFO_CTR *ctr, prs_struct *ps, int depth) { - if (fl3 == NULL) + if (ctr == NULL) return False; - prs_debug(ps, depth, desc, "srv_io_file_3_fl3"); + prs_debug(ps, depth, desc, "srv_io_srv_file_ctr"); depth++; + if (UNMARSHALLING(ps)) { + memset(ctr, '\0', sizeof(SRV_FILE_INFO_CTR)); + } + if(!prs_align(ps)) return False; - if(!prs_uint32("num_entries_read", ps, depth, &fl3->num_entries_read)) + if(!prs_uint32("switch_value", ps, depth, &ctr->switch_value)) return False; - if(!prs_uint32("ptr_file_fl3", ps, depth, &fl3->ptr_file_info)) + if (ctr->switch_value != 3) { + DEBUG(5,("%s File info %d level not supported\n", + tab_depth(depth), ctr->switch_value)); + } + if(!prs_uint32("ptr_file_info", ps, depth, &ctr->ptr_file_info)) + return False; + if(!prs_uint32("num_entries", ps, depth, &ctr->num_entries)) + return False; + if(!prs_uint32("ptr_entries", ps, depth, &ctr->ptr_entries)) + return False; + if (ctr->ptr_entries == 0) + return True; + if(!prs_uint32("num_entries2", ps, depth, + &ctr->num_entries2)) return False; - if (fl3->ptr_file_info != 0) { + switch (ctr->switch_value) { + case 3: { + SRV_FILE_INFO_3 *info3 = ctr->file.info3; + int num_entries = ctr->num_entries; int i; - int num_entries = fl3->num_entries_read; - if (num_entries > MAX_FILE_ENTRIES) { - num_entries = MAX_FILE_ENTRIES; /* report this! */ + if (UNMARSHALLING(ps)) { + if (!(info3 = (SRV_FILE_INFO_3 *)prs_alloc_mem(ps, num_entries * sizeof(SRV_FILE_INFO_3)))) + return False; + ctr->file.info3 = info3; } - if(!prs_uint32("num_entries_read2", ps, depth, &fl3->num_entries_read2)) - return False; - for (i = 0; i < num_entries; i++) { - if(!srv_io_file_info3("", &fl3->info_3[i], ps, depth)) + if(!srv_io_file_info3("", &ctr->file.info3[i].info_3, ps, depth)) return False; } - for (i = 0; i < num_entries; i++) { - if(!srv_io_file_info3_str("", &fl3->info_3_str[i], ps, depth)) + if(!srv_io_file_info3_str("", &ctr->file.info3[i].info_3_str, ps, depth)) return False; } - - if(!prs_align(ps)) - return False; - } - - return True; -} - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -static BOOL srv_io_srv_file_ctr(char *desc, SRV_FILE_INFO_CTR **pp_ctr, prs_struct *ps, int depth) -{ - SRV_FILE_INFO_CTR *ctr = *pp_ctr; - - if (UNMARSHALLING(ps)) { - ctr = *pp_ctr = (SRV_FILE_INFO_CTR *)prs_alloc_mem(ps, sizeof(SRV_FILE_INFO_CTR)); - if (ctr == NULL) - return False; + break; } - - if (ctr == NULL) - return False; - - prs_debug(ps, depth, desc, "srv_io_srv_file_ctr"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("switch_value", ps, depth, &ctr->switch_value)) - return False; - if(!prs_uint32("ptr_file_ctr", ps, depth, &ctr->ptr_file_ctr)) - return False; - - if (ctr->ptr_file_ctr != 0) { - switch (ctr->switch_value) { - case 3: - if(!srv_io_srv_file_info_3("", &ctr->file.info3, ps, depth)) - return False; - break; - default: - DEBUG(5,("%s no file info at switch_value %d\n", - tab_depth(depth), ctr->switch_value)); - break; - } + default: + DEBUG(5,("%s no file info at switch_value %d\n", + tab_depth(depth), ctr->switch_value)); + break; } - + return True; } @@ -1972,20 +2004,22 @@ static BOOL srv_io_srv_file_ctr(char *desc, SRV_FILE_INFO_CTR **pp_ctr, prs_stru ********************************************************************/ void init_srv_q_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n, - char *srv_name, char *qual_name, - uint32 file_level, SRV_FILE_INFO_CTR *ctr, - uint32 preferred_len, - ENUM_HND *hnd) + char *srv_name, char *qual_name, char *user_name, + uint32 file_level, SRV_FILE_INFO_CTR *ctr, + uint32 preferred_len, + ENUM_HND *hnd) { DEBUG(5,("init_q_net_file_enum\n")); - q_n->ctr = ctr; - init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name); init_buf_unistr2(&q_n->uni_qual_name, &q_n->ptr_qual_name, qual_name); + init_buf_unistr2(&q_n->uni_user_name, &q_n->ptr_user_name, user_name); - q_n->file_level = file_level; + q_n->file_level = q_n->ctr.switch_value = file_level; q_n->preferred_len = preferred_len; + q_n->ctr.ptr_file_info = 1; + q_n->ctr.num_entries = 0; + q_n->ctr.num_entries2 = 0; memcpy(&q_n->enum_hnd, hnd, sizeof(*hnd)); } @@ -2021,6 +2055,13 @@ BOOL srv_io_q_net_file_enum(char *desc, SRV_Q_NET_FILE_ENUM *q_n, prs_struct *ps if(!prs_align(ps)) return False; + if(!prs_uint32("ptr_user_name", ps, depth, &q_n->ptr_user_name)) + return False; + if(!smb_io_unistr2("", &q_n->uni_user_name, q_n->ptr_user_name, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; if(!prs_uint32("file_level", ps, depth, &q_n->file_level)) return False; @@ -2071,6 +2112,68 @@ BOOL srv_io_r_net_file_enum(char *desc, SRV_R_NET_FILE_ENUM *r_n, prs_struct *ps return True; } +/******************************************************************* + Initialize a net file close request +********************************************************************/ +void init_srv_q_net_file_close(SRV_Q_NET_FILE_CLOSE *q_n, char *server, + uint32 file_id) +{ + q_n->ptr_srv_name = 1; + init_unistr2(&q_n->uni_srv_name, server, strlen(server) + 1); + q_n->file_id = file_id; +} + +/******************************************************************* + Reads or writes a structure. +********************************************************************/ +BOOL srv_io_q_net_file_close(char *desc, SRV_Q_NET_FILE_CLOSE *q_n, + prs_struct *ps, int depth) +{ + if (q_n == NULL) + return False; + + prs_debug(ps, depth, desc, "srv_io_q_net_file_close"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("ptr_srv_name", ps, depth, &q_n->ptr_srv_name)) + return False; + if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("file_id", ps, depth, &q_n->file_id)) + return False; + + return True; +} + +/******************************************************************* + Reads or writes a structure. +********************************************************************/ + +BOOL srv_io_r_net_file_close(char *desc, SRV_R_NET_FILE_CLOSE *q_n, + prs_struct *ps, int depth) +{ + if (q_n == NULL) + return False; + + prs_debug(ps, depth, desc, "srv_io_r_net_file_close"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_werror("status", ps, depth, &q_n->status)) + return False; + + return True; +} + /******************************************************************* Inits a SRV_INFO_100 structure. ********************************************************************/ @@ -2907,3 +3010,14 @@ BOOL srv_io_r_net_file_set_secdesc(char *desc, SRV_R_NET_FILE_SET_SECDESC *r_n, return True; } + +/******************************************************************* + Inits a structure +********************************************************************/ + +void init_srv_q_net_remote_tod(SRV_Q_NET_REMOTE_TOD *q_u, char *server) +{ + q_u->ptr_srv_name = 1; + init_unistr2(&q_u->uni_srv_name, server, strlen(server) + 1); +} + diff --git a/source3/rpc_parse/parse_wks.c b/source3/rpc_parse/parse_wks.c index 3846c2e3b6..7b8fd76b7b 100644 --- a/source3/rpc_parse/parse_wks.c +++ b/source3/rpc_parse/parse_wks.c @@ -22,6 +22,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_PARSE + /******************************************************************* Init ********************************************************************/ -- cgit