diff options
-rw-r--r-- | source3/groupdb/mapping.c | 10 | ||||
-rw-r--r-- | source3/include/rpc_lsa.h | 13 | ||||
-rw-r--r-- | source3/libsmb/cli_lsarpc.c | 174 | ||||
-rw-r--r-- | source3/rpc_parse/parse_lsa.c | 77 | ||||
-rw-r--r-- | source3/rpcclient/cmd_lsarpc.c | 104 |
5 files changed, 370 insertions, 8 deletions
diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index 678824d812..92a98ff7a4 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -66,6 +66,16 @@ PRIVS privs[] = { { 25, "SeUndockPrivilege" }, { 26, "SeSyncAgentPrivilege" }, { 27, "SeEnableDelegationPrivilege" }, +SeNetworkLogonRight +SeUnsolicitedInputPrivilege +SeBatchLogonRight +SeServiceLogonRight +SeInteractiveLogonRight +SeDenyInteractiveLogonRight +SeDenyNetworkLogonRight +SeDenyBatchLogonRight +SeDenyBatchLogonRight + }; */ diff --git a/source3/include/rpc_lsa.h b/source3/include/rpc_lsa.h index a9a28a63ac..f3edac6873 100644 --- a/source3/include/rpc_lsa.h +++ b/source3/include/rpc_lsa.h @@ -570,6 +570,19 @@ typedef struct lsa_r_getsystemaccount } LSA_R_GETSYSTEMACCOUNT; +typedef struct lsa_q_lookupprivvalue +{ + POLICY_HND pol; /* policy handle */ + UNIHDR hdr_right; + UNISTR2 uni2_right; +} LSA_Q_LOOKUPPRIVVALUE; + +typedef struct lsa_r_lookupprivvalue +{ + LUID luid; + NTSTATUS status; +} LSA_R_LOOKUPPRIVVALUE; + #endif /* _RPC_LSA_H */ /* diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index e944734292..ffe86eccd5 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -815,4 +815,178 @@ NTSTATUS cli_lsa_enum_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/** Open a LSA user handle + * + * @param cli Handle on an initialised SMB connection */ + +NTSTATUS cli_lsa_open_account(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *dom_pol, DOM_SID *sid, uint32 des_access, + POLICY_HND *user_pol) +{ + prs_struct qbuf, rbuf; + LSA_Q_OPENACCOUNT q; + LSA_R_OPENACCOUNT r; + NTSTATUS result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_lsa_q_open_account(&q, dom_pol, sid, des_access); + + /* Marshall data and send request */ + + if (!lsa_io_q_open_account("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, LSA_OPENACCOUNT, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!lsa_io_r_open_account("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + + if (NT_STATUS_IS_OK(result = r.status)) { + *user_pol = r.pol; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/** Enumerate user privileges + * + * @param cli Handle on an initialised SMB connection */ + +NTSTATUS cli_lsa_enum_privsaccount(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 *count, LUID_ATTR **set) +{ + prs_struct qbuf, rbuf; + LSA_Q_ENUMPRIVSACCOUNT q; + LSA_R_ENUMPRIVSACCOUNT r; + NTSTATUS result; + int i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_lsa_q_enum_privsaccount(&q, pol); + + /* Marshall data and send request */ + + if (!lsa_io_q_enum_privsaccount("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, LSA_ENUMPRIVSACCOUNT, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!lsa_io_r_enum_privsaccount("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + + if (!NT_STATUS_IS_OK(result = r.status)) { + goto done; + } + + if (r.count == 0) + goto done; + + if (!((*set = (LUID_ATTR *)talloc(mem_ctx, sizeof(LUID_ATTR) * r.count)))) { + DEBUG(0, ("(cli_lsa_enum_privsaccount): out of memory\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + for (i=0; i<r.count; i++) { + (*set)[i].luid.low = r.set.set[i].luid.low; + (*set)[i].luid.high = r.set.set[i].luid.high; + (*set)[i].attr = r.set.set[i].attr; + } + + *count=r.count; + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/** Get a privilege value given its name */ + +NTSTATUS cli_lsa_lookupprivvalue(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, char *name, LUID *luid) +{ + prs_struct qbuf, rbuf; + LSA_Q_LOOKUPPRIVVALUE q; + LSA_R_LOOKUPPRIVVALUE r; + NTSTATUS result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_lsa_q_lookupprivvalue(&q, pol, name); + + if (!lsa_io_q_lookupprivvalue("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, LSA_LOOKUPPRIVVALUE, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!lsa_io_r_lookupprivvalue("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + if (!NT_STATUS_IS_OK(result = r.status)) { + goto done; + } + + /* Return output parameters */ + + (*luid).low=r.luid.low; + (*luid).high=r.luid.high; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + + /** @} **/ diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c index 10a9efbe49..d7ef923be9 100644 --- a/source3/rpc_parse/parse_lsa.c +++ b/source3/rpc_parse/parse_lsa.c @@ -1660,6 +1660,14 @@ BOOL lsa_io_r_unk_get_connuser(char *desc, LSA_R_UNK_GET_CONNUSER *r_c, prs_stru return True; } +void init_lsa_q_open_account(LSA_Q_OPENACCOUNT *trn, POLICY_HND *hnd, DOM_SID *sid, uint32 access) +{ + memcpy(&trn->pol, hnd, sizeof(trn->pol)); + + init_dom_sid2(&trn->sid, sid); + trn->access = access; +} + /******************************************************************* Reads or writes an LSA_Q_OPENACCOUNT structure. ********************************************************************/ @@ -1675,7 +1683,7 @@ BOOL lsa_io_q_open_account(char *desc, LSA_Q_OPENACCOUNT *r_c, prs_struct *ps, i if(!smb_io_pol_hnd("pol", &r_c->pol, ps, depth)) return False; - if(!smb_io_dom_sid2("", &r_c->sid, ps, depth)) /* domain SID */ + if(!smb_io_dom_sid2("sid", &r_c->sid, ps, depth)) /* domain SID */ return False; if(!prs_uint32("access", ps, depth, &r_c->access)) @@ -1706,6 +1714,12 @@ BOOL lsa_io_r_open_account(char *desc, LSA_R_OPENACCOUNT *r_c, prs_struct *ps, } +void init_lsa_q_enum_privsaccount(LSA_Q_ENUMPRIVSACCOUNT *trn, POLICY_HND *hnd) +{ + memcpy(&trn->pol, hnd, sizeof(trn->pol)); + +} + /******************************************************************* Reads or writes an LSA_Q_ENUMPRIVSACCOUNT structure. ********************************************************************/ @@ -1822,6 +1836,12 @@ BOOL lsa_io_r_enum_privsaccount(char *desc, LSA_R_ENUMPRIVSACCOUNT *r_c, prs_str return False; /* malloc memory if unmarshalling here */ + + if (UNMARSHALLING(ps) && r_c->count!=0) { + if (!(r_c->set.set = (LUID_ATTR *)prs_alloc_mem(ps,sizeof(LUID_ATTR) * r_c->count))) + return False; + + } if(!lsa_io_privilege_set(desc, &r_c->set, ps, depth)) return False; @@ -1873,3 +1893,58 @@ BOOL lsa_io_r_getsystemaccount(char *desc, LSA_R_GETSYSTEMACCOUNT *r_c, prs_str return True; } + +void init_lsa_q_lookupprivvalue(LSA_Q_LOOKUPPRIVVALUE *trn, POLICY_HND *hnd, char *name) +{ + int len_name = strlen(name); + memcpy(&trn->pol, hnd, sizeof(trn->pol)); + + if(len_name == 0) + len_name = 1; + + init_uni_hdr(&trn->hdr_right, len_name); + init_unistr2(&trn->uni2_right, name, len_name); +} + +/******************************************************************* + Reads or writes an LSA_Q_LOOKUPPRIVVALUE structure. +********************************************************************/ + +BOOL lsa_io_q_lookupprivvalue(char *desc, LSA_Q_LOOKUPPRIVVALUE *r_c, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "lsa_io_q_lookupprivvalue"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!smb_io_pol_hnd("pol", &r_c->pol, ps, depth)) + return False; + if(!smb_io_unihdr ("hdr_name", &r_c->hdr_right, ps, depth)) + return False; + if(!smb_io_unistr2("uni2_right", &r_c->uni2_right, r_c->hdr_right.buffer, ps, depth)) + return False; + + return True; +} + +/******************************************************************* + Reads or writes an LSA_R_LOOKUPPRIVVALUE structure. +********************************************************************/ + +BOOL lsa_io_r_lookupprivvalue(char *desc, LSA_R_LOOKUPPRIVVALUE *r_c, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "lsa_io_r_lookupprivvalue"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!lsa_io_luid("luid", &r_c->luid, ps, depth)) + return False; + + if(!prs_ntstatus("status", ps, depth, &r_c->status)) + return False; + + return True; +} diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index d9b6540b77..9e1ab7be1b 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -366,19 +366,109 @@ static NTSTATUS cmd_lsa_enum_sids(struct cli_state *cli, return result; } +/* Enumerate the privileges of an SID */ + +static NTSTATUS cmd_lsa_enum_privsaccounts(struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, + char **argv) +{ + POLICY_HND dom_pol; + POLICY_HND user_pol; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + uint32 access_desired = 0x000f000f; + + DOM_SID sid; + uint32 count=0; + LUID_ATTR *set; + int i; + + if (argc != 2 ) { + printf("Usage: %s SID\n", argv[0]); + return NT_STATUS_OK; + } + + string_to_sid(&sid, argv[1]); + + result = cli_lsa_open_policy2(cli, mem_ctx, True, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &dom_pol); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + result = cli_lsa_open_account(cli, mem_ctx, &dom_pol, &sid, access_desired, &user_pol); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + result = cli_lsa_enum_privsaccount(cli, mem_ctx, &user_pol, &count, &set); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + /* Print results */ + printf("found %d privileges for SID %s\n\n", count, argv[1]); + printf("high\tlow\tattribute\n"); + + for (i = 0; i < count; i++) { + printf("%u\t%u\t%u\n", set[i].luid.high, set[i].luid.low, set[i].attr); + } + + done: + return result; +} + +/* Get a privilege value given its name */ + +static NTSTATUS cmd_lsa_lookupprivvalue(struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, + char **argv) +{ + POLICY_HND pol; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + DOM_SID sid; + LUID luid; + + if (argc != 2 ) { + printf("Usage: %s name\n", argv[0]); + return NT_STATUS_OK; + } + + result = cli_lsa_open_policy2(cli, mem_ctx, True, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &pol); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + result = cli_lsa_lookupprivvalue(cli, mem_ctx, &pol, argv[1], &luid); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + /* Print results */ + printf("%u:%u (0x%x:0x%x)\n", luid.high, luid.low, luid.high, luid.low); + + done: + return result; +} + /* List of commands exported by this module */ struct cmd_set lsarpc_commands[] = { { "LSARPC" }, - { "lsaquery", cmd_lsa_query_info_policy, PIPE_LSARPC, "Query info policy", "" }, - { "lookupsids", cmd_lsa_lookup_sids, PIPE_LSARPC, "Convert SIDs to names", "" }, - { "lookupnames", cmd_lsa_lookup_names, PIPE_LSARPC, "Convert names to SIDs", "" }, - { "enumtrust", cmd_lsa_enum_trust_dom, PIPE_LSARPC, "Enumerate trusted domains", "" }, - { "enumprivs", cmd_lsa_enum_privilege, PIPE_LSARPC, "Enumerate privileges", "" }, - { "getdispname", cmd_lsa_get_dispname, PIPE_LSARPC, "Get the privilege name", "" }, - { "lsaenumsid", cmd_lsa_enum_sids, PIPE_LSARPC, "Enumerate the LSA SIDS", "" }, + { "lsaquery", cmd_lsa_query_info_policy, PIPE_LSARPC, "Query info policy", "" }, + { "lookupsids", cmd_lsa_lookup_sids, PIPE_LSARPC, "Convert SIDs to names", "" }, + { "lookupnames", cmd_lsa_lookup_names, PIPE_LSARPC, "Convert names to SIDs", "" }, + { "enumtrust", cmd_lsa_enum_trust_dom, PIPE_LSARPC, "Enumerate trusted domains", "" }, + { "enumprivs", cmd_lsa_enum_privilege, PIPE_LSARPC, "Enumerate privileges", "" }, + { "getdispname", cmd_lsa_get_dispname, PIPE_LSARPC, "Get the privilege name", "" }, + { "lsaenumsid", cmd_lsa_enum_sids, PIPE_LSARPC, "Enumerate the LSA SIDS", "" }, + { "lsaenumprivsaccount", cmd_lsa_enum_privsaccounts, PIPE_LSARPC, "Enumerate the privileges of an SID", "" }, + { "lsalookupprivvalue", cmd_lsa_lookupprivvalue, PIPE_LSARPC, "Get a privilege value given its name", "" }, { NULL } }; |