From 655b04e4f8585a952afe226e602995ebbc7d1600 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 11 Apr 2006 15:47:24 +0000 Subject: r15041: Adding rpc client calls to manipulate auditing policies on remote CIFS servers. Also add a new "net rpc audit" tool. The lsa query infolevels were taken from samb4 IDL, the lsa policy flags and categories are partly documented on msdn. I need to cleanup the double lsa_query_info_policy{2}{_new} calls next. Guenther (This used to be commit 0fed66926f4b72444abfc8ffb8c46cca8d0600aa) --- source3/Makefile.in | 4 +- source3/include/rpc_lsa.h | 174 ++++++++++------ source3/lib/audit.c | 149 ++++++++++++++ source3/rpc_client/cli_lsarpc.c | 139 +++++++++++-- source3/rpc_parse/parse_lsa.c | 434 +++++++++++++++++++++++++++++----------- source3/rpc_server/srv_lsa_nt.c | 53 +++-- source3/rpcclient/cmd_lsarpc.c | 156 +++++++++++---- source3/utils/net_rpc.c | 1 + source3/utils/net_rpc_audit.c | 414 ++++++++++++++++++++++++++++++++++++++ 9 files changed, 1272 insertions(+), 252 deletions(-) create mode 100644 source3/lib/audit.c create mode 100644 source3/utils/net_rpc_audit.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 3b3bd75de9..8f3112c7e2 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -222,7 +222,7 @@ LIB_OBJ = $(VERSION_OBJ) lib/charcnv.o lib/debug.o lib/fault.o \ lib/adt_tree.o lib/gencache.o $(TDB_OBJ) \ lib/module.o lib/events.o lib/ldap_escape.o @CHARSET_STATIC@ \ lib/secdesc.o lib/util_seaccess.o lib/secace.o lib/secacl.o @SOCKWRAP@ \ - libads/krb5_errs.o lib/system_smbd.o + libads/krb5_errs.o lib/system_smbd.o lib/audit.o LIB_DUMMY_OBJ = lib/dummysmbd.o lib/dummyroot.o LIB_NONSMBD_OBJ = $(LIB_OBJ) $(LIB_DUMMY_OBJ) @@ -572,7 +572,7 @@ NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_ads_cldap.o utils/net_help.o \ utils/net_status.o utils/net_rpc_printer.o utils/net_rpc_rights.o \ utils/net_rpc_service.o utils/net_rpc_registry.o utils/net_usershare.o \ utils/netlookup.o utils/net_sam.o utils/net_rpc_shell.o \ - utils/net_util.o utils/net_rpc_sh_acct.o + utils/net_util.o utils/net_rpc_sh_acct.o utils/net_rpc_audit.o NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \ $(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \ diff --git a/source3/include/rpc_lsa.h b/source3/include/rpc_lsa.h index 493ac1ab00..c4ce9e021d 100644 --- a/source3/include/rpc_lsa.h +++ b/source3/include/rpc_lsa.h @@ -86,8 +86,54 @@ /* XXXX these are here to get a compile! */ #define LSA_LOOKUPRIDS 0xFD +#define LSA_AUDIT_NUM_CATEGORIES_NT4 7 +#define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9 + +#define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4 + +#define LSA_AUDIT_POLICY_NONE 0x00 +#define LSA_AUDIT_POLICY_SUCCESS 0x01 +#define LSA_AUDIT_POLICY_FAILURE 0x02 +#define LSA_AUDIT_POLICY_ALL (LSA_AUDIT_POLICY_SUCCESS|LSA_AUDIT_POLICY_FAILURE) +#define LSA_AUDIT_POLICY_CLEAR 0x04 + +enum lsa_audit_categories { + LSA_AUDIT_CATEGORY_SYSTEM = 0, + LSA_AUDIT_CATEGORY_LOGON = 1, + LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS, + LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS, + LSA_AUDIT_CATEGORY_PROCCESS_TRACKING, + LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES, + LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT, + LSA_AUDIT_CATEGORY_DIRECTORY_SERVICE_ACCESS, /* only in win2k/2k3 */ + LSA_AUDIT_CATEGORY_ACCOUNT_LOGON /* only in win2k/2k3 */ +}; + +/* level 1 is auditing settings */ +typedef struct dom_query_1 +{ + uint32 percent_full; + uint32 log_size; + NTTIME retention_time; + uint8 shutdown_in_progress; + NTTIME time_to_shutdown; + uint32 next_audit_record; + uint32 unknown; +} DOM_QUERY_1; + + +/* level 2 is auditing settings */ +typedef struct dom_query_2 +{ + uint32 auditing_enabled; + uint32 count1; /* usualy 7, at least on nt4sp4 */ + uint32 count2; /* the same */ + uint32 ptr; + uint32 *auditsettings; +} DOM_QUERY_2; + /* DOM_QUERY - info class 3 and 5 LSA Query response */ -typedef struct dom_query_info +typedef struct dom_query_info_3 { uint16 uni_dom_max_len; /* domain name string length * 2 */ uint16 uni_dom_str_len; /* domain name string length * 2 */ @@ -96,20 +142,10 @@ typedef struct dom_query_info UNISTR2 uni_domain_name; /* domain name (unicode string) */ DOM_SID2 dom_sid; /* domain SID */ -} DOM_QUERY; +} DOM_QUERY_3; /* level 5 is same as level 3. */ -typedef DOM_QUERY DOM_QUERY_3; -typedef DOM_QUERY DOM_QUERY_5; - -/* level 2 is auditing settings */ -typedef struct dom_query_2 -{ - uint32 auditing_enabled; - uint32 count1; /* usualy 7, at least on nt4sp4 */ - uint32 count2; /* the same */ - uint32 *auditsettings; -} DOM_QUERY_2; +typedef DOM_QUERY_3 DOM_QUERY_5; /* level 6 is server role information */ typedef struct dom_query_6 @@ -117,6 +153,37 @@ typedef struct dom_query_6 uint16 server_role; /* 2=backup, 3=primary */ } DOM_QUERY_6; +/* level 10 is audit full set info */ +typedef struct dom_query_10 +{ + uint8 shutdown_on_full; +} DOM_QUERY_10; + +/* level 11 is audit full query info */ +typedef struct dom_query_11 +{ + uint16 unknown; + uint8 shutdown_on_full; + uint8 log_is_full; +} DOM_QUERY_11; + +/* level 12 is DNS domain info */ +typedef struct lsa_dns_dom_info +{ + UNIHDR hdr_nb_dom_name; /* netbios domain name */ + UNIHDR hdr_dns_dom_name; + UNIHDR hdr_forest_name; + + struct uuid dom_guid; /* domain GUID */ + + UNISTR2 uni_nb_dom_name; + UNISTR2 uni_dns_dom_name; + UNISTR2 uni_forest_name; + + uint32 ptr_dom_sid; + DOM_SID2 dom_sid; /* domain SID */ +} DOM_QUERY_12; + typedef struct seq_qos_info { uint32 len; /* 12 */ @@ -245,67 +312,56 @@ typedef struct r_lsa_query_sec_obj_info typedef struct lsa_query_info { POLICY_HND pol; /* policy handle */ - uint16 info_class; /* info class */ + uint16 info_class; /* info class */ } LSA_Q_QUERY_INFO; -/* LSA_INFO_UNION */ -typedef union lsa_info_union +/* LSA_INFO_CTR */ +typedef struct lsa_info_ctr { - DOM_QUERY_2 id2; - DOM_QUERY_3 id3; - DOM_QUERY_5 id5; - DOM_QUERY_6 id6; -} LSA_INFO_UNION; - -/* LSA_R_QUERY_INFO - response to LSA query info policy */ -typedef struct lsa_r_query_info -{ - uint32 undoc_buffer; /* undocumented buffer pointer */ - uint16 info_class; /* info class (same as info class in request) */ - - LSA_INFO_UNION dom; + uint16 info_class; + union { + DOM_QUERY_1 id1; + DOM_QUERY_2 id2; + DOM_QUERY_3 id3; + DOM_QUERY_5 id5; + DOM_QUERY_6 id6; + DOM_QUERY_10 id10; + DOM_QUERY_11 id11; + DOM_QUERY_12 id12; + } info; - NTSTATUS status; /* return code */ +} LSA_INFO_CTR; -} LSA_R_QUERY_INFO; +typedef LSA_INFO_CTR LSA_INFO_CTR2; -/* LSA_DNS_DOM_INFO - DNS domain info - info class 12*/ -typedef struct lsa_dns_dom_info +/* LSA_Q_SET_INFO - LSA set info policy */ +typedef struct lsa_set_info { - UNIHDR hdr_nb_dom_name; /* netbios domain name */ - UNIHDR hdr_dns_dom_name; - UNIHDR hdr_forest_name; + POLICY_HND pol; /* policy handle */ + uint16 info_class; /* info class */ + LSA_INFO_CTR ctr; - struct uuid dom_guid; /* domain GUID */ +} LSA_Q_SET_INFO; - UNISTR2 uni_nb_dom_name; - UNISTR2 uni_dns_dom_name; - UNISTR2 uni_forest_name; +/* LSA_R_SET_INFO - response to LSA set info policy */ +typedef struct lsa_r_set_info +{ + NTSTATUS status; /* return code */ - uint32 ptr_dom_sid; - DOM_SID2 dom_sid; /* domain SID */ -} LSA_DNS_DOM_INFO; +} LSA_R_SET_INFO; -typedef union lsa_info2_union +/* LSA_R_QUERY_INFO - response to LSA query info policy */ +typedef struct lsa_r_query_info { - LSA_DNS_DOM_INFO dns_dom_info; -} LSA_INFO2_UNION; + uint32 dom_ptr; /* undocumented buffer pointer */ + LSA_INFO_CTR ctr; + NTSTATUS status; /* return code */ -/* LSA_Q_QUERY_INFO2 - LSA query info */ -typedef struct lsa_q_query_info2 -{ - POLICY_HND pol; /* policy handle */ - uint16 info_class; /* info class */ -} LSA_Q_QUERY_INFO2; +} LSA_R_QUERY_INFO; -typedef struct lsa_r_query_info2 -{ - uint32 ptr; /* pointer to info struct */ - uint16 info_class; - LSA_INFO2_UNION info; /* so far the only one */ - NTSTATUS status; -} LSA_R_QUERY_INFO2; +typedef LSA_Q_QUERY_INFO LSA_Q_QUERY_INFO2; +typedef LSA_R_QUERY_INFO LSA_R_QUERY_INFO2; /*******************************************************/ diff --git a/source3/lib/audit.c b/source3/lib/audit.c new file mode 100644 index 0000000000..86bd30bdff --- /dev/null +++ b/source3/lib/audit.c @@ -0,0 +1,149 @@ +/* + Unix SMB/CIFS implementation. + Auditing helper functions. + Copyright (C) Guenther Deschner 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 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" + +static const struct audit_category_tab { + uint32 category; + const char *category_str; + const char *param_str; + const char *description; +} audit_category_tab [] = { + { LSA_AUDIT_CATEGORY_LOGON, + "LSA_AUDIT_CATEGORY_LOGON", + "LOGON", "Logon events" }, + { LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS, + "LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS", + "PRIVILEGE", "Privilege Use" }, + { LSA_AUDIT_CATEGORY_SYSTEM, + "LSA_AUDIT_CATEGORY_SYSTEM", + "SYSTEM", "System Events" }, + { LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES, + "LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES", + "POLICY", "Policy Change" }, + { LSA_AUDIT_CATEGORY_PROCCESS_TRACKING, + "LSA_AUDIT_CATEGORY_PROCCESS_TRACKING", + "PROCESS", "Process Tracking" }, + { LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS, + "LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS", + "OBJECT", "Object Access" }, + { LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT, + "LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT", + "SAM", "Account Management" }, + { LSA_AUDIT_CATEGORY_DIRECTORY_SERVICE_ACCESS, + "LSA_AUDIT_CATEGORY_DIRECTORY_SERVICE_ACCESS", + "DIRECTORY", "Directory service access" }, + { LSA_AUDIT_CATEGORY_ACCOUNT_LOGON, + "LSA_AUDIT_CATEGORY_ACCOUNT_LOGON", + "ACCOUNT", "Account logon events" }, + { 0, NULL, NULL } +}; + +const char *audit_category_str(uint32 category) +{ + int i; + for (i=0; audit_category_tab[i].category_str; i++) { + if (category == audit_category_tab[i].category) { + return audit_category_tab[i].category_str; + } + } + return NULL; +} + +const char *audit_param_str(uint32 category) +{ + int i; + for (i=0; audit_category_tab[i].param_str; i++) { + if (category == audit_category_tab[i].category) { + return audit_category_tab[i].param_str; + } + } + return NULL; +} + +const char *audit_description_str(uint32 category) +{ + int i; + for (i=0; audit_category_tab[i].description; i++) { + if (category == audit_category_tab[i].category) { + return audit_category_tab[i].description; + } + } + return NULL; +} + +BOOL get_audit_category_from_param(const char *param, uint32 *audit_category) +{ + *audit_category = Undefined; + + if (strequal(param, "SYSTEM")) { + *audit_category = LSA_AUDIT_CATEGORY_SYSTEM; + } else if (strequal(param, "LOGON")) { + *audit_category = LSA_AUDIT_CATEGORY_LOGON; + } else if (strequal(param, "OBJECT")) { + *audit_category = LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS; + } else if (strequal(param, "PRIVILEGE")) { + *audit_category = LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS; + } else if (strequal(param, "PROCESS")) { + *audit_category = LSA_AUDIT_CATEGORY_PROCCESS_TRACKING; + } else if (strequal(param, "POLICY")) { + *audit_category = LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES; + } else if (strequal(param, "SAM")) { + *audit_category = LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT; + } else if (strequal(param, "DIRECTORY")) { + *audit_category = LSA_AUDIT_CATEGORY_DIRECTORY_SERVICE_ACCESS; + } else if (strequal(param, "ACCOUNT")) { + *audit_category = LSA_AUDIT_CATEGORY_ACCOUNT_LOGON; + } else { + DEBUG(0,("unknown parameter: %s\n", param)); + return False; + } + + return True; +} + +const char *audit_policy_str(TALLOC_CTX *mem_ctx, uint32 policy) +{ + const char *ret = NULL; + + if (policy == LSA_AUDIT_POLICY_NONE) { + return talloc_strdup(mem_ctx, "None"); + } + + if (policy & LSA_AUDIT_POLICY_SUCCESS) { + ret = talloc_strdup(mem_ctx, "Success"); + if (ret == NULL) { + return NULL; + } + } + + if (policy & LSA_AUDIT_POLICY_FAILURE) { + if (ret) { + ret = talloc_asprintf(mem_ctx, "%s, %s", ret, "Failure"); + if (ret == NULL) { + return NULL; + } + } else { + return talloc_strdup(mem_ctx, "Failure"); + } + } + + return ret; +} diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c index 7c08a3c2e4..ac797243ed 100644 --- a/source3/rpc_client/cli_lsarpc.c +++ b/source3/rpc_client/cli_lsarpc.c @@ -378,6 +378,76 @@ NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli, return result; } +NTSTATUS rpccli_lsa_query_info_policy_new(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint16 info_class, + LSA_INFO_CTR *ctr) +{ + prs_struct qbuf, rbuf; + LSA_Q_QUERY_INFO q; + LSA_R_QUERY_INFO r; + NTSTATUS result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + init_q_query(&q, pol, info_class); + + CLI_DO_RPC(cli, mem_ctx, PI_LSARPC, LSA_QUERYINFOPOLICY, + q, r, + qbuf, rbuf, + lsa_io_q_query, + lsa_io_r_query, + NT_STATUS_UNSUCCESSFUL); + + result = r.status; + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + done: + + *ctr = r.ctr; + + return result; +} + +NTSTATUS rpccli_lsa_query_info_policy2_new(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint16 info_class, + LSA_INFO_CTR2 *ctr) +{ + prs_struct qbuf, rbuf; + LSA_Q_QUERY_INFO2 q; + LSA_R_QUERY_INFO2 r; + NTSTATUS result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + init_q_query2(&q, pol, info_class); + + CLI_DO_RPC(cli, mem_ctx, PI_LSARPC, LSA_QUERYINFO2, + q, r, + qbuf, rbuf, + lsa_io_q_query_info2, + lsa_io_r_query_info2, + NT_STATUS_UNSUCCESSFUL); + + result = r.status; + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + done: + + *ctr = r.ctr; + + return result; +} + + + /** Query info policy * * @param domain_sid - returned remote server's domain sid */ @@ -415,42 +485,42 @@ NTSTATUS rpccli_lsa_query_info_policy(struct rpc_pipe_client *cli, switch (info_class) { case 3: - if (domain_name && (r.dom.id3.buffer_dom_name != 0)) { + if (domain_name && (r.ctr.info.id3.buffer_dom_name != 0)) { *domain_name = unistr2_tdup(mem_ctx, - &r.dom.id3. + &r.ctr.info.id3. uni_domain_name); if (!*domain_name) { return NT_STATUS_NO_MEMORY; } } - if (domain_sid && (r.dom.id3.buffer_dom_sid != 0)) { + if (domain_sid && (r.ctr.info.id3.buffer_dom_sid != 0)) { *domain_sid = TALLOC_P(mem_ctx, DOM_SID); if (!*domain_sid) { return NT_STATUS_NO_MEMORY; } - sid_copy(*domain_sid, &r.dom.id3.dom_sid.sid); + sid_copy(*domain_sid, &r.ctr.info.id3.dom_sid.sid); } break; case 5: - if (domain_name && (r.dom.id5.buffer_dom_name != 0)) { + if (domain_name && (r.ctr.info.id5.buffer_dom_name != 0)) { *domain_name = unistr2_tdup(mem_ctx, - &r.dom.id5. + &r.ctr.info.id5. uni_domain_name); if (!*domain_name) { return NT_STATUS_NO_MEMORY; } } - if (domain_sid && (r.dom.id5.buffer_dom_sid != 0)) { + if (domain_sid && (r.ctr.info.id5.buffer_dom_sid != 0)) { *domain_sid = TALLOC_P(mem_ctx, DOM_SID); if (!*domain_sid) { return NT_STATUS_NO_MEMORY; } - sid_copy(*domain_sid, &r.dom.id5.dom_sid.sid); + sid_copy(*domain_sid, &r.ctr.info.id5.dom_sid.sid); } break; @@ -510,25 +580,25 @@ NTSTATUS rpccli_lsa_query_info_policy2(struct rpc_pipe_client *cli, ZERO_STRUCTP(domain_guid); - if (domain_name && r.info.dns_dom_info.hdr_nb_dom_name.buffer) { + if (domain_name && r.ctr.info.id12.hdr_nb_dom_name.buffer) { *domain_name = unistr2_tdup(mem_ctx, - &r.info.dns_dom_info + &r.ctr.info.id12 .uni_nb_dom_name); if (!*domain_name) { return NT_STATUS_NO_MEMORY; } } - if (dns_name && r.info.dns_dom_info.hdr_dns_dom_name.buffer) { + if (dns_name && r.ctr.info.id12.hdr_dns_dom_name.buffer) { *dns_name = unistr2_tdup(mem_ctx, - &r.info.dns_dom_info + &r.ctr.info.id12 .uni_dns_dom_name); if (!*dns_name) { return NT_STATUS_NO_MEMORY; } } - if (forest_name && r.info.dns_dom_info.hdr_forest_name.buffer) { + if (forest_name && r.ctr.info.id12.hdr_forest_name.buffer) { *forest_name = unistr2_tdup(mem_ctx, - &r.info.dns_dom_info + &r.ctr.info.id12 .uni_forest_name); if (!*forest_name) { return NT_STATUS_NO_MEMORY; @@ -541,17 +611,17 @@ NTSTATUS rpccli_lsa_query_info_policy2(struct rpc_pipe_client *cli, return NT_STATUS_NO_MEMORY; } memcpy(*domain_guid, - &r.info.dns_dom_info.dom_guid, + &r.ctr.info.id12.dom_guid, sizeof(struct uuid)); } - if (domain_sid && r.info.dns_dom_info.ptr_dom_sid != 0) { + if (domain_sid && r.ctr.info.id12.ptr_dom_sid != 0) { *domain_sid = TALLOC_P(mem_ctx, DOM_SID); if (!*domain_sid) { return NT_STATUS_NO_MEMORY; } sid_copy(*domain_sid, - &r.info.dns_dom_info.dom_sid.sid); + &r.ctr.info.id12.dom_sid.sid); } done: @@ -559,6 +629,41 @@ NTSTATUS rpccli_lsa_query_info_policy2(struct rpc_pipe_client *cli, return result; } +NTSTATUS rpccli_lsa_set_info_policy(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint16 info_class, + LSA_INFO_CTR ctr) +{ + prs_struct qbuf, rbuf; + LSA_Q_SET_INFO q; + LSA_R_SET_INFO r; + NTSTATUS result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + init_q_set(&q, pol, info_class, ctr); + + CLI_DO_RPC(cli, mem_ctx, PI_LSARPC, LSA_SETINFOPOLICY, + q, r, + qbuf, rbuf, + lsa_io_q_set, + lsa_io_r_set, + NT_STATUS_UNSUCCESSFUL); + + result = r.status; + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + /* Return output parameters */ + + done: + + return result; +} + + /** * Enumerate list of trusted domains * diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c index b7c0fa3814..ffc0f04332 100644 --- a/source3/rpc_parse/parse_lsa.c +++ b/source3/rpc_parse/parse_lsa.c @@ -673,16 +673,90 @@ BOOL lsa_io_r_enum_trust_dom(const char *desc, LSA_R_ENUM_TRUST_DOM *out, return True; } +/******************************************************************* +reads or writes a structure. +********************************************************************/ + +static BOOL lsa_io_dom_query_1(const char *desc, DOM_QUERY_1 *d_q, prs_struct *ps, int depth) +{ + if (d_q == NULL) + return False; + + prs_debug(ps, depth, desc, "lsa_io_dom_query_1"); + depth++; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("percent_full", ps, depth, &d_q->percent_full)) + return False; + if (!prs_uint32("log_size", ps, depth, &d_q->log_size)) + return False; + if (!smb_io_nttime("retention_time", ps, depth, &d_q->retention_time)) + return False; + if (!prs_uint8("shutdown_in_progress", ps, depth, &d_q->shutdown_in_progress)) + return False; + if (!smb_io_nttime("time_to_shutdown", ps, depth, &d_q->time_to_shutdown)) + return False; + if (!prs_uint32("next_audit_record", ps, depth, &d_q->next_audit_record)) + return False; + if (!prs_uint32("unknown", ps, depth, &d_q->unknown)) + return False; + + return True; +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ + +static BOOL lsa_io_dom_query_2(const char *desc, DOM_QUERY_2 *d_q, prs_struct *ps, int depth) +{ + if (d_q == NULL) + return False; + + prs_debug(ps, depth, desc, "lsa_io_dom_query_2"); + depth++; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("auditing_enabled", ps, depth, &d_q->auditing_enabled)) + return False; + if (!prs_uint32("ptr ", ps, depth, &d_q->ptr)) + return False; + if (!prs_uint32("count1", ps, depth, &d_q->count1)) + return False; + + if (d_q->ptr) { + + if (!prs_uint32("count2", ps, depth, &d_q->count2)) + return False; + + if (d_q->count1 != d_q->count2) + return False; + + if (UNMARSHALLING(ps)) { + d_q->auditsettings = TALLOC_ZERO_ARRAY(ps->mem_ctx, uint32, d_q->count2); + } + + if (!prs_uint32s(False, "auditsettings", ps, depth, d_q->auditsettings, d_q->count2)) + return False; + } + + return True; +} + /******************************************************************* reads or writes a dom query structure. ********************************************************************/ -static BOOL lsa_io_dom_query(const char *desc, DOM_QUERY *d_q, prs_struct *ps, int depth) +static BOOL lsa_io_dom_query_3(const char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth) { if (d_q == NULL) return False; - prs_debug(ps, depth, desc, "lsa_io_dom_query"); + prs_debug(ps, depth, desc, "lsa_io_dom_query_3"); depth++; if(!prs_align(ps)) @@ -715,79 +789,235 @@ static BOOL lsa_io_dom_query(const char *desc, DOM_QUERY *d_q, prs_struct *ps, i } /******************************************************************* -reads or writes a structure. + Reads or writes a dom query structure. ********************************************************************/ -static BOOL lsa_io_dom_query_2(const char *desc, DOM_QUERY_2 *d_q, prs_struct *ps, int depth) +static BOOL lsa_io_dom_query_5(const char *desc, DOM_QUERY_5 *d_q, prs_struct *ps, int depth) { - uint32 ptr = 1; + return lsa_io_dom_query_3("", d_q, ps, depth); +} +/******************************************************************* + Reads or writes a dom query structure. +********************************************************************/ + +static BOOL lsa_io_dom_query_6(const char *desc, DOM_QUERY_6 *d_q, prs_struct *ps, int depth) +{ if (d_q == NULL) return False; - prs_debug(ps, depth, desc, "lsa_io_dom_query_2"); + prs_debug(ps, depth, desc, "lsa_io_dom_query_6"); depth++; - if (!prs_align(ps)) + if (!prs_uint16("server_role", ps, depth, &d_q->server_role)) return False; - if (!prs_uint32("auditing_enabled", ps, depth, &d_q->auditing_enabled)) - return False; - if (!prs_uint32("ptr ", ps, depth, &ptr)) - return False; - if (!prs_uint32("count1", ps, depth, &d_q->count1)) + return True; +} + +/******************************************************************* + Reads or writes a dom query structure. +********************************************************************/ + +static BOOL lsa_io_dom_query_10(const char *desc, DOM_QUERY_10 *d_q, prs_struct *ps, int depth) +{ + if (d_q == NULL) return False; - if (!prs_uint32("count2", ps, depth, &d_q->count2)) + + prs_debug(ps, depth, desc, "lsa_io_dom_query_10"); + depth++; + + if (!prs_uint8("shutdown_on_full", ps, depth, &d_q->shutdown_on_full)) return False; - if (UNMARSHALLING(ps)) { - d_q->auditsettings = TALLOC_ZERO_ARRAY(ps->mem_ctx, uint32, d_q->count2); - } + return True; +} + +/******************************************************************* + Reads or writes a dom query structure. +********************************************************************/ - if (d_q->auditsettings == NULL) { - DEBUG(1, ("lsa_io_dom_query_2: NULL auditsettings!\n")); +static BOOL lsa_io_dom_query_11(const char *desc, DOM_QUERY_11 *d_q, prs_struct *ps, int depth) +{ + if (d_q == NULL) return False; - } - if (!prs_uint32s(False, "auditsettings", ps, depth, d_q->auditsettings, d_q->count2)) + prs_debug(ps, depth, desc, "lsa_io_dom_query_11"); + depth++; + + if (!prs_uint16("unknown", ps, depth, &d_q->unknown)) + return False; + if (!prs_uint8("shutdown_on_full", ps, depth, &d_q->shutdown_on_full)) + return False; + if (!prs_uint8("log_is_full", ps, depth, &d_q->log_is_full)) return False; - return True; + return True; } /******************************************************************* - Reads or writes a dom query structure. + Reads or writes an LSA_DNS_DOM_INFO structure. ********************************************************************/ -static BOOL lsa_io_dom_query_3(const char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth) +BOOL lsa_io_dom_query_12(const char *desc, DOM_QUERY_12 *info, prs_struct *ps, int depth) { - return lsa_io_dom_query("", d_q, ps, depth); + prs_debug(ps, depth, desc, "lsa_io_dom_query_12"); + depth++; + + if(!prs_align(ps)) + return False; + if(!smb_io_unihdr("nb_name", &info->hdr_nb_dom_name, ps, depth)) + return False; + if(!smb_io_unihdr("dns_name", &info->hdr_dns_dom_name, ps, depth)) + return False; + if(!smb_io_unihdr("forest", &info->hdr_forest_name, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; + if ( !smb_io_uuid("dom_guid", &info->dom_guid, ps, depth) ) + return False; + + if(!prs_align(ps)) + return False; + if(!prs_uint32("dom_sid", ps, depth, &info->ptr_dom_sid)) + return False; + + if(!smb_io_unistr2("nb_name", &info->uni_nb_dom_name, + info->hdr_nb_dom_name.buffer, ps, depth)) + return False; + if(!smb_io_unistr2("dns_name", &info->uni_dns_dom_name, + info->hdr_dns_dom_name.buffer, ps, depth)) + return False; + if(!smb_io_unistr2("forest", &info->uni_forest_name, + info->hdr_forest_name.buffer, ps, depth)) + return False; + + if(!smb_io_dom_sid2("dom_sid", &info->dom_sid, ps, depth)) + return False; + + return True; + } /******************************************************************* - Reads or writes a dom query structure. + Inits an LSA_Q_QUERY_INFO structure. ********************************************************************/ -static BOOL lsa_io_dom_query_5(const char *desc, DOM_QUERY_5 *d_q, prs_struct *ps, int depth) +void init_q_set(LSA_Q_SET_INFO *in, POLICY_HND *hnd, uint16 info_class, LSA_INFO_CTR ctr) { - return lsa_io_dom_query("", d_q, ps, depth); + DEBUG(5,("init_q_set\n")); + + in->info_class = info_class; + + in->pol = *hnd; + + in->ctr = ctr; + in->ctr.info_class = info_class; } /******************************************************************* - Reads or writes a dom query structure. +reads or writes a structure. ********************************************************************/ -static BOOL lsa_io_dom_query_6(const char *desc, DOM_QUERY_6 *d_q, prs_struct *ps, int depth) +static BOOL lsa_io_query_info_ctr2(const char *desc, prs_struct *ps, int depth, LSA_INFO_CTR2 *ctr) { - if (d_q == NULL) + prs_debug(ps, depth, desc, "lsa_io_query_info_ctr2"); + depth++; + + if(!prs_uint16("info_class", ps, depth, &ctr->info_class)) return False; - prs_debug(ps, depth, desc, "lsa_io_dom_query_6"); + switch (ctr->info_class) { + case 1: + if(!lsa_io_dom_query_1("", &ctr->info.id1, ps, depth)) + return False; + break; + case 2: + if(!lsa_io_dom_query_2("", &ctr->info.id2, ps, depth)) + return False; + break; + case 3: + if(!lsa_io_dom_query_3("", &ctr->info.id3, ps, depth)) + return False; + break; + case 5: + if(!lsa_io_dom_query_5("", &ctr->info.id5, ps, depth)) + return False; + break; + case 6: + if(!lsa_io_dom_query_6("", &ctr->info.id6, ps, depth)) + return False; + break; + case 10: + if(!lsa_io_dom_query_10("", &ctr->info.id10, ps, depth)) + return False; + break; + case 11: + if(!lsa_io_dom_query_11("", &ctr->info.id11, ps, depth)) + return False; + break; + case 12: + if(!lsa_io_dom_query_12("", &ctr->info.id12, ps, depth)) + return False; + break; + default: + DEBUG(0,("invalid info_class: %d\n", ctr->info_class)); + return False; + break; + } + + return True; +} + + +/******************************************************************* +reads or writes a structure. +********************************************************************/ + +static BOOL lsa_io_query_info_ctr(const char *desc, prs_struct *ps, int depth, LSA_INFO_CTR *ctr) +{ + prs_debug(ps, depth, desc, "lsa_io_query_info_ctr"); depth++; - if (!prs_uint16("server_role", ps, depth, &d_q->server_role)) + if(!prs_uint16("info_class", ps, depth, &ctr->info_class)) return False; + switch (ctr->info_class) { + case 1: + if(!lsa_io_dom_query_1("", &ctr->info.id1, ps, depth)) + return False; + break; + case 2: + if(!lsa_io_dom_query_2("", &ctr->info.id2, ps, depth)) + return False; + break; + case 3: + if(!lsa_io_dom_query_3("", &ctr->info.id3, ps, depth)) + return False; + break; + case 5: + if(!lsa_io_dom_query_5("", &ctr->info.id5, ps, depth)) + return False; + break; + case 6: + if(!lsa_io_dom_query_6("", &ctr->info.id6, ps, depth)) + return False; + break; + case 10: + if(!lsa_io_dom_query_10("", &ctr->info.id10, ps, depth)) + return False; + break; + case 11: + if(!lsa_io_dom_query_11("", &ctr->info.id11, ps, depth)) + return False; + break; + default: + DEBUG(0,("invalid info_class: %d\n", ctr->info_class)); + return False; + break; + } + return True; } @@ -797,40 +1027,20 @@ static BOOL lsa_io_dom_query_6(const char *desc, DOM_QUERY_6 *d_q, prs_struct *p BOOL lsa_io_r_query(const char *desc, LSA_R_QUERY_INFO *out, prs_struct *ps, int depth) { + prs_debug(ps, depth, desc, "lsa_io_r_query"); depth++; - if(!prs_uint32("undoc_buffer", ps, depth, &out->undoc_buffer)) + if(!prs_align(ps)) return False; - if (out->undoc_buffer != 0) { - if(!prs_uint16("info_class", ps, depth, &out->info_class)) - return False; + if(!prs_uint32("dom_ptr", ps, depth, &out->dom_ptr)) + return False; - if(!prs_align(ps)) - return False; + if (out->dom_ptr) { - switch (out->info_class) { - case 2: - if(!lsa_io_dom_query_2("", &out->dom.id2, ps, depth)) - return False; - break; - case 3: - if(!lsa_io_dom_query_3("", &out->dom.id3, ps, depth)) - return False; - break; - case 5: - if(!lsa_io_dom_query_5("", &out->dom.id5, ps, depth)) - return False; - break; - case 6: - if(!lsa_io_dom_query_6("", &out->dom.id6, ps, depth)) - return False; - break; - default: - /* PANIC! */ - break; - } + if(!lsa_io_query_info_ctr("", ps, depth, &out->ctr)) + return False; } if(!prs_align(ps)) @@ -842,6 +1052,49 @@ BOOL lsa_io_r_query(const char *desc, LSA_R_QUERY_INFO *out, prs_struct *ps, int return True; } +/******************************************************************* + Reads or writes an LSA_Q_SET_INFO structure. +********************************************************************/ + +BOOL lsa_io_q_set(const char *desc, LSA_Q_SET_INFO *in, prs_struct *ps, + int depth) +{ + prs_debug(ps, depth, desc, "lsa_io_q_set"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!smb_io_pol_hnd("", &in->pol, ps, depth)) + return False; + + if(!prs_uint16("info_class", ps, depth, &in->info_class)) + return False; + + if(!lsa_io_query_info_ctr("", ps, depth, &in->ctr)) + return False; + + return True; +} + +/******************************************************************* + Reads or writes an LSA_R_SET_INFO structure. +********************************************************************/ + +BOOL lsa_io_r_set(const char *desc, LSA_R_SET_INFO *out, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "lsa_io_r_set"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_ntstatus("status", ps, depth, &out->status)) + return False; + + return True; +} + /******************************************************************* Inits a LSA_SID_ENUM structure. ********************************************************************/ @@ -2851,52 +3104,6 @@ BOOL policy_handle_is_valid(const POLICY_HND *hnd) return ((memcmp(&zero_pol, hnd, sizeof(POLICY_HND)) == 0) ? False : True ); } -/******************************************************************* - Reads or writes an LSA_DNS_DOM_INFO structure. -********************************************************************/ - -BOOL lsa_io_dns_dom_info(const char *desc, LSA_DNS_DOM_INFO *info, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_dns_dom_info"); - depth++; - - if(!prs_align(ps)) - return False; - if(!smb_io_unihdr("nb_name", &info->hdr_nb_dom_name, ps, depth)) - return False; - if(!smb_io_unihdr("dns_name", &info->hdr_dns_dom_name, ps, depth)) - return False; - if(!smb_io_unihdr("forest", &info->hdr_forest_name, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - if ( !smb_io_uuid("dom_guid", &info->dom_guid, ps, depth) ) - return False; - - if(!prs_align(ps)) - return False; - if(!prs_uint32("dom_sid", ps, depth, &info->ptr_dom_sid)) - return False; - - if(!smb_io_unistr2("nb_name", &info->uni_nb_dom_name, - info->hdr_nb_dom_name.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("dns_name", &info->uni_dns_dom_name, - info->hdr_dns_dom_name.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("forest", &info->uni_forest_name, - info->hdr_forest_name.buffer, ps, depth)) - return False; - - if(!smb_io_dom_sid2("dom_sid", &info->dom_sid, ps, depth)) - return False; - - return True; - -} - /******************************************************************* Inits an LSA_Q_QUERY_INFO2 structure. ********************************************************************/ @@ -2944,20 +3151,13 @@ BOOL lsa_io_r_query_info2(const char *desc, LSA_R_QUERY_INFO2 *out, if(!prs_align(ps)) return False; - if(!prs_uint32("ptr", ps, depth, &out->ptr)) + if(!prs_uint32("dom_ptr", ps, depth, &out->dom_ptr)) return False; - if(!prs_uint16("info_class", ps, depth, &out->info_class)) - return False; - switch(out->info_class) { - case 0x000c: - if (!lsa_io_dns_dom_info("info12", &out->info.dns_dom_info, - ps, depth)) + + if (out->dom_ptr) { + + if(!lsa_io_query_info_ctr2("", ps, depth, &out->ctr)) return False; - break; - default: - DEBUG(0,("lsa_io_r_query_info2: unknown info class %d\n", - out->info_class)); - return False; } if(!prs_align(ps)) diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 7fe42efefb..1f74f24296 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -62,7 +62,7 @@ static void free_lsa_info(void *ptr) Init dom_query ***************************************************************************/ -static void init_dom_query(DOM_QUERY *d_q, const char *dom_name, DOM_SID *dom_sid) +static void init_dom_query_3(DOM_QUERY_3 *d_q, const char *dom_name, DOM_SID *dom_sid) { d_q->buffer_dom_name = (dom_name != NULL) ? 1 : 0; /* domain buffer pointer */ d_q->buffer_dom_sid = (dom_sid != NULL) ? 1 : 0; /* domain sid pointer */ @@ -93,6 +93,15 @@ static void init_dom_query(DOM_QUERY *d_q, const char *dom_name, DOM_SID *dom_si init_dom_sid2(&d_q->dom_sid, dom_sid); } +/*************************************************************************** +Init dom_query + ***************************************************************************/ + +static void init_dom_query_5(DOM_QUERY_5 *d_q, const char *dom_name, DOM_SID *dom_sid) +{ + return init_dom_query_3(d_q, dom_name, dom_sid); +} + /*************************************************************************** init_dom_ref - adds a domain if it's not already in, returns the index. ***************************************************************************/ @@ -678,7 +687,7 @@ NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO *r_u) { struct lsa_info *handle; - LSA_INFO_UNION *info = &r_u->dom; + LSA_INFO_CTR *ctr = &r_u->ctr; DOM_SID domain_sid; const char *name; DOM_SID *sid = NULL; @@ -691,19 +700,31 @@ NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INF switch (q_u->info_class) { case 0x02: { - unsigned int i; + + uint32 policy_def = LSA_AUDIT_POLICY_ALL; + /* check if the user have enough rights */ - if (!(handle->access & POLICY_VIEW_AUDIT_INFORMATION)) + if (!(handle->access & POLICY_VIEW_AUDIT_INFORMATION)) { + DEBUG(10,("_lsa_query_info: insufficient access rights\n")); return NT_STATUS_ACCESS_DENIED; + } /* fake info: We audit everything. ;) */ - info->id2.auditing_enabled = 1; - info->id2.count1 = 7; - info->id2.count2 = 7; - if ((info->id2.auditsettings = TALLOC_ARRAY(p->mem_ctx,uint32, 7)) == NULL) + ctr->info.id2.ptr = 1; + ctr->info.id2.auditing_enabled = True; + ctr->info.id2.count1 = ctr->info.id2.count2 = LSA_AUDIT_NUM_CATEGORIES; + + if ((ctr->info.id2.auditsettings = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, LSA_AUDIT_NUM_CATEGORIES)) == NULL) return NT_STATUS_NO_MEMORY; - for (i = 0; i < 7; i++) - info->id2.auditsettings[i] = 3; + + ctr->info.id2.auditsettings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def; + ctr->info.id2.auditsettings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def; + ctr->info.id2.auditsettings[LSA_AUDIT_CATEGORY_LOGON] = policy_def; + ctr->info.id2.auditsettings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def; + ctr->info.id2.auditsettings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def; + ctr->info.id2.auditsettings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def; + ctr->info.id2.auditsettings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def; + break; } case 0x03: @@ -733,7 +754,7 @@ NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INF default: return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } - init_dom_query(&r_u->dom.id3, name, sid); + init_dom_query_3(&r_u->ctr.info.id3, name, sid); break; case 0x05: /* check if the user have enough rights */ @@ -743,7 +764,7 @@ NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INF /* Request PolicyAccountDomainInformation. */ name = get_global_sam_name(); sid = get_global_sam_sid(); - init_dom_query(&r_u->dom.id5, name, sid); + init_dom_query_5(&r_u->ctr.info.id5, name, sid); break; case 0x06: /* check if the user have enough rights */ @@ -756,14 +777,14 @@ NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INF * only a BDC is a backup controller * of the domain, it controls. */ - info->id6.server_role = 2; + ctr->info.id6.server_role = 2; break; default: /* * any other role is a primary * of the domain, it controls. */ - info->id6.server_role = 3; + ctr->info.id6.server_role = 3; break; } break; @@ -774,8 +795,8 @@ NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INF } if (NT_STATUS_IS_OK(r_u->status)) { - r_u->undoc_buffer = 0x22000000; /* bizarre */ - r_u->info_class = q_u->info_class; + r_u->dom_ptr = 0x22000000; /* bizarre */ + ctr->info_class = q_u->info_class; } return r_u->status; diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index 21097649cb..0e22b98287 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -59,8 +59,109 @@ done: return result; } +static void display_query_info_1(DOM_QUERY_1 d) +{ + d_printf("percent_full:\t%d\n", d.percent_full); + d_printf("log_size:\t%d\n", d.log_size); + d_printf("retention_time:\t%08x %08x\n", d.retention_time.high, d.retention_time.low); + d_printf("shutdown_in_progress:\t%d\n", d.shutdown_in_progress); + d_printf("time_to_shutdown:\t%08x %08x\n", d.time_to_shutdown.high, d.time_to_shutdown.low); + d_printf("next_audit_record:\t%d\n", d.next_audit_record); + d_printf("unknown:\t%d\n", d.unknown); +} + +static void display_query_info_2(DOM_QUERY_2 d, TALLOC_CTX *mem_ctx) +{ + int i; + d_printf("Auditing enabled:\t%d\n", d.auditing_enabled); + d_printf("Auditing categories:\t%d\n", d.count1); + d_printf("Auditsettings:\n"); + for (i=0; iinfo_class) { + case 1: + display_query_info_1(dom->info.id1); + break; + case 2: + display_query_info_2(dom->info.id2, mem_ctx); + break; + case 3: + display_query_info_3(dom->info.id3); + break; + case 5: + display_query_info_5(dom->info.id5); + break; + case 10: + display_query_info_10(dom->info.id10); + break; + case 11: + display_query_info_11(dom->info.id11); + break; + case 12: + display_query_info_12(dom->info.id12); + break; + default: + printf("can't display info level: %d\n", dom->info_class); + break; + } +} static NTSTATUS cmd_lsa_query_info_policy(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, @@ -68,11 +169,7 @@ static NTSTATUS cmd_lsa_query_info_policy(struct rpc_pipe_client *cli, { POLICY_HND pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_SID *dom_sid = NULL; - struct uuid *dom_guid; - char *domain_name = NULL; - char *dns_name = NULL; - char *forest_name = NULL; + LSA_INFO_CTR dom; uint32 info_class = 3; @@ -83,56 +180,33 @@ static NTSTATUS cmd_lsa_query_info_policy(struct rpc_pipe_client *cli, if (argc == 2) info_class = atoi(argv[1]); - - /* Lookup info policy */ + switch (info_class) { case 12: result = rpccli_lsa_open_policy2(cli, mem_ctx, True, - SEC_RIGHTS_MAXIMUM_ALLOWED, - &pol); + SEC_RIGHTS_MAXIMUM_ALLOWED, + &pol); if (!NT_STATUS_IS_OK(result)) goto done; - result = rpccli_lsa_query_info_policy2(cli, mem_ctx, &pol, - info_class, &domain_name, - &dns_name, &forest_name, - &dom_guid, &dom_sid); + + result = rpccli_lsa_query_info_policy2_new(cli, mem_ctx, &pol, + info_class, &dom); break; default: result = rpccli_lsa_open_policy(cli, mem_ctx, True, - SEC_RIGHTS_MAXIMUM_ALLOWED, - &pol); + SEC_RIGHTS_MAXIMUM_ALLOWED, + &pol); if (!NT_STATUS_IS_OK(result)) goto done; - result = rpccli_lsa_query_info_policy(cli, mem_ctx, &pol, - info_class, &domain_name, - &dom_sid); + + result = rpccli_lsa_query_info_policy_new(cli, mem_ctx, &pol, + info_class, &dom); } - if (!NT_STATUS_IS_OK(result)) - goto done; - - if (domain_name) { - if (dom_sid == NULL) { - printf("got no sid for domain %s\n", domain_name); - } else { - printf("domain %s has sid %s\n", domain_name, - sid_string_static(dom_sid)); - } - } else { - printf("could not query info for level %d\n", info_class); - } - if (dns_name) - printf("domain dns name is %s\n", dns_name); - if (forest_name) - printf("forest name is %s\n", forest_name); - - if (info_class == 12) { - printf("domain GUID is %s\n", - smb_uuid_string_static(*dom_guid)); - } + display_lsa_query_info(&dom, mem_ctx); rpccli_lsa_close(cli, mem_ctx, &pol); diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 26d224651f..420bc1245e 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -6649,6 +6649,7 @@ int net_rpc_help(int argc, const char **argv) int net_rpc(int argc, const char **argv) { struct functable func[] = { + {"audit", net_rpc_audit}, {"info", net_rpc_info}, {"join", net_rpc_join}, {"oldjoin", net_rpc_oldjoin}, diff --git a/source3/utils/net_rpc_audit.c b/source3/utils/net_rpc_audit.c new file mode 100644 index 0000000000..5c81fe24d0 --- /dev/null +++ b/source3/utils/net_rpc_audit.c @@ -0,0 +1,414 @@ +/* + Samba Unix/Linux SMB client library + Distributed SMB/CIFS Server Management Utility + Copyright (C) 2006 Guenther Deschner + + 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" +#include "utils/net.h" + +/******************************************************************** +********************************************************************/ + +static int net_help_audit(int argc, const char **argv) +{ + d_printf("net rpc audit list View configured Auditing policies\n"); + d_printf("net rpc audit enable Enable Auditing\n"); + d_printf("net rpc audit disable Disable Auditing\n"); + d_printf("net rpc audit get View configured Auditing policy setting\n"); + d_printf("net rpc audit set Set Auditing policies\n\n"); + d_printf("\tcategory can be one of: SYSTEM, LOGON, OBJECT, PRIVILEGE, PROCESS, POLICY, SAM, DIRECTORY or ACCOUNT\n"); + d_printf("\tpolicy can be one of: SUCCESS, FAILURE, ALL or NONE\n\n"); + + return -1; +} + +/******************************************************************** +********************************************************************/ + +static void print_auditing_category(const char *policy, const char *value) +{ + fstring padding; + int pad_len, col_len = 30; + + /* calculate padding space for d_printf to look nicer */ + pad_len = col_len - strlen(policy); + padding[pad_len] = 0; + do padding[--pad_len] = ' '; while (pad_len > 0); + + d_printf("\t%s%s%s\n", policy, padding, value); +} + + +/******************************************************************** +********************************************************************/ + +static NTSTATUS rpc_audit_get_internal(const DOM_SID *domain_sid, + const char *domain_name, + struct cli_state *cli, + struct rpc_pipe_client *pipe_hnd, + TALLOC_CTX *mem_ctx, + int argc, + const char **argv) +{ + POLICY_HND pol; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + LSA_INFO_CTR dom; + int i; + + uint32 info_class = 2; + uint32 audit_category; + + if (argc < 1 || argc > 2) { + d_printf("insufficient arguments\n"); + net_help_audit(argc, argv); + return NT_STATUS_INVALID_PARAMETER; + } + + if (!get_audit_category_from_param(argv[0], &audit_category)) { + d_printf("invalid auditing category: %s\n", argv[0]); + return NT_STATUS_INVALID_PARAMETER; + } + + result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &pol); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + result = rpccli_lsa_query_info_policy_new(pipe_hnd, mem_ctx, &pol, + info_class, + &dom); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + for (i=0; i < dom.info.id2.count1; i++) { + + const char *val = NULL, *policy = NULL; + + if (i != audit_category) { + continue; + } + + val = audit_policy_str(mem_ctx, dom.info.id2.auditsettings[i]); + policy = audit_description_str(i); + print_auditing_category(policy, val); + } + + done: + if (!NT_STATUS_IS_OK(result)) { + d_printf("failed to get auditing policy: %s\n", nt_errstr(result)); + } + + return result; +} + +/******************************************************************** +********************************************************************/ + +static NTSTATUS rpc_audit_set_internal(const DOM_SID *domain_sid, + const char *domain_name, + struct cli_state *cli, + struct rpc_pipe_client *pipe_hnd, + TALLOC_CTX *mem_ctx, + int argc, + const char **argv) +{ + POLICY_HND pol; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + LSA_INFO_CTR dom; + + uint32 info_class = 2; + uint32 audit_policy, audit_category; + + if (argc < 2 || argc > 3) { + d_printf("insufficient arguments\n"); + net_help_audit(argc, argv); + return NT_STATUS_INVALID_PARAMETER; + } + + if (!get_audit_category_from_param(argv[0], &audit_category)) { + d_printf("invalid auditing category: %s\n", argv[0]); + return NT_STATUS_INVALID_PARAMETER; + } + + audit_policy = LSA_AUDIT_POLICY_CLEAR; + + if (strequal(argv[1], "Success")) { + audit_policy |= LSA_AUDIT_POLICY_SUCCESS; + } else if (strequal(argv[1], "Failure")) { + audit_policy |= LSA_AUDIT_POLICY_FAILURE; + } else if (strequal(argv[1], "All")) { + audit_policy |= LSA_AUDIT_POLICY_ALL; + } else if (strequal(argv[1], "None")) { + audit_policy = LSA_AUDIT_POLICY_CLEAR; + } else { + d_printf("invalid auditing policy: %s\n", argv[1]); + return NT_STATUS_INVALID_PARAMETER; + } + + result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &pol); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + result = rpccli_lsa_query_info_policy_new(pipe_hnd, mem_ctx, &pol, + info_class, + &dom); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + dom.info.id2.auditsettings[audit_category] = audit_policy; + + result = rpccli_lsa_set_info_policy(pipe_hnd, mem_ctx, &pol, + info_class, + dom); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + result = rpccli_lsa_query_info_policy_new(pipe_hnd, mem_ctx, &pol, + info_class, + &dom); + + { + const char *val = audit_policy_str(mem_ctx, dom.info.id2.auditsettings[audit_category]); + const char *policy = audit_description_str(audit_category); + print_auditing_category(policy, val); + } + + done: + if (!NT_STATUS_IS_OK(result)) { + d_printf("failed to set audit policy: %s\n", nt_errstr(result)); + } + + return result; +} + +static NTSTATUS rpc_audit_enable_internal_ext(struct rpc_pipe_client *pipe_hnd, + TALLOC_CTX *mem_ctx, + int argc, + const char **argv, + BOOL enable) +{ + POLICY_HND pol; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + LSA_INFO_CTR dom; + + uint32 info_class = 2; + + result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &pol); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + result = rpccli_lsa_query_info_policy_new(pipe_hnd, mem_ctx, &pol, + info_class, + &dom); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + dom.info.id2.auditing_enabled = enable; + + result = rpccli_lsa_set_info_policy(pipe_hnd, mem_ctx, &pol, + info_class, + dom); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + done: + if (!NT_STATUS_IS_OK(result)) { + d_printf("failed to %s audit policy: %s\n", enable ? "enable":"disable", + nt_errstr(result)); + } + + return result; +} +/******************************************************************** +********************************************************************/ + +static NTSTATUS rpc_audit_disable_internal(const DOM_SID *domain_sid, + const char *domain_name, + struct cli_state *cli, + struct rpc_pipe_client *pipe_hnd, + TALLOC_CTX *mem_ctx, + int argc, + const char **argv) +{ + return rpc_audit_enable_internal_ext(pipe_hnd, mem_ctx, argc, argv, False); +} + +/******************************************************************** +********************************************************************/ + +static NTSTATUS rpc_audit_enable_internal(const DOM_SID *domain_sid, + const char *domain_name, + struct cli_state *cli, + struct rpc_pipe_client *pipe_hnd, + TALLOC_CTX *mem_ctx, + int argc, + const char **argv) +{ + return rpc_audit_enable_internal_ext(pipe_hnd, mem_ctx, argc, argv, True); +} + +/******************************************************************** +********************************************************************/ + +static NTSTATUS rpc_audit_list_internal(const DOM_SID *domain_sid, + const char *domain_name, + struct cli_state *cli, + struct rpc_pipe_client *pipe_hnd, + TALLOC_CTX *mem_ctx, + int argc, + const char **argv) +{ + POLICY_HND pol; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + LSA_INFO_CTR dom; + int i; + + uint32 info_class = 2; + + result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &pol); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + result = rpccli_lsa_query_info_policy_new(pipe_hnd, mem_ctx, &pol, + info_class, + &dom); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + printf("Auditing:\t\t"); + switch (dom.info.id2.auditing_enabled) { + case True: + printf("Enabled"); + break; + case False: + printf("Disabled"); + break; + default: + printf("unknown (%d)", dom.info.id2.auditing_enabled); + break; + } + printf("\n"); + + printf("Auditing categories:\t%d\n", dom.info.id2.count1); + printf("Auditing settings:\n"); + + for (i=0; i < dom.info.id2.count1; i++) { + const char *val = audit_policy_str(mem_ctx, dom.info.id2.auditsettings[i]); + const char *policy = audit_description_str(i); + print_auditing_category(policy, val); + } + + done: + if (!NT_STATUS_IS_OK(result)) { + d_printf("failed to list auditing policies: %s\n", nt_errstr(result)); + } + + return result; +} + + + +/******************************************************************** +********************************************************************/ + +static int rpc_audit_get(int argc, const char **argv) +{ + return run_rpc_command(NULL, PI_LSARPC, 0, + rpc_audit_get_internal, argc, argv); +} + +/******************************************************************** +********************************************************************/ + +static int rpc_audit_set(int argc, const char **argv) +{ + return run_rpc_command(NULL, PI_LSARPC, 0, + rpc_audit_set_internal, argc, argv); +} + +/******************************************************************** +********************************************************************/ + +static int rpc_audit_enable(int argc, const char **argv) +{ + return run_rpc_command(NULL, PI_LSARPC, 0, + rpc_audit_enable_internal, argc, argv); +} + +/******************************************************************** +********************************************************************/ + +static int rpc_audit_disable(int argc, const char **argv) +{ + return run_rpc_command(NULL, PI_LSARPC, 0, + rpc_audit_disable_internal, argc, argv); +} + +/******************************************************************** +********************************************************************/ + +static int rpc_audit_list(int argc, const char **argv) +{ + return run_rpc_command(NULL, PI_LSARPC, 0, + rpc_audit_list_internal, argc, argv); +} + +/******************************************************************** +********************************************************************/ + +int net_rpc_audit(int argc, const char **argv) +{ + struct functable func[] = { + {"get", rpc_audit_get}, + {"set", rpc_audit_set}, + {"enable", rpc_audit_enable}, + {"disable", rpc_audit_disable}, + {"list", rpc_audit_list}, + {NULL, NULL} + }; + + if (argc) + return net_run_function(argc, argv, func, net_help_audit); + + return net_help_audit(argc, argv); +} -- cgit