diff options
-rw-r--r-- | source3/include/rpc_lsa.h | 25 | ||||
-rw-r--r-- | source3/include/rpc_misc.h | 6 | ||||
-rw-r--r-- | source3/rpc_client/cli_lsarpc.c | 40 | ||||
-rw-r--r-- | source3/rpc_parse/parse_lsa.c | 74 | ||||
-rw-r--r-- | source3/rpc_parse/parse_misc.c | 41 | ||||
-rw-r--r-- | source3/rpcclient/cmd_lsarpc.c | 74 |
6 files changed, 240 insertions, 20 deletions
diff --git a/source3/include/rpc_lsa.h b/source3/include/rpc_lsa.h index a220b3f70d..78dbae4cdf 100644 --- a/source3/include/rpc_lsa.h +++ b/source3/include/rpc_lsa.h @@ -515,23 +515,38 @@ typedef struct lsa_r_enum_privs NTSTATUS status; } LSA_R_ENUM_PRIVS; -/* LSA_Q_ENUM_ACCOUNTS - LSA enum account rights */ +/* LSA_Q_ENUM_ACCT_RIGHTS - LSA enum account rights */ typedef struct lsa_q_enum_acct_rights { POLICY_HND pol; /* policy handle */ - uint32 count; /* what is this for in the query? */ - DOM_SID sid; + DOM_SID2 sid; } LSA_Q_ENUM_ACCT_RIGHTS; -/* LSA_R_ENUM_ACCOUNTS - LSA enum account rights */ +/* LSA_R_ENUM_ACCT_RIGHTS - LSA enum account rights */ typedef struct lsa_r_enum_acct_rights { uint32 count; - UNISTR_ARRAY rights; + UNISTR2_ARRAY rights; NTSTATUS status; } LSA_R_ENUM_ACCT_RIGHTS; +/* LSA_Q_ADD_ACCT_RIGHTS - LSA add account rights */ +typedef struct +{ + POLICY_HND pol; /* policy handle */ + DOM_SID2 sid; + UNISTR2_ARRAY rights; + uint32 count; +} LSA_Q_ADD_ACCT_RIGHTS; + +/* LSA_R_ADD_ACCT_RIGHTS - LSA add account rights */ +typedef struct lsa_r_add_acct_rights +{ + NTSTATUS status; +} LSA_R_ADD_ACCT_RIGHTS; + + /* LSA_Q_PRIV_GET_DISPNAME - LSA get privilege display name */ typedef struct lsa_q_priv_get_dispname { diff --git a/source3/include/rpc_misc.h b/source3/include/rpc_misc.h index 1b956826eb..7710489435 100644 --- a/source3/include/rpc_misc.h +++ b/source3/include/rpc_misc.h @@ -217,15 +217,15 @@ typedef struct uint16 size; uint32 ref_id; UNISTR2 string; -} UNISTR_ARRAY_EL; +} UNISTR2_ARRAY_EL; /* an array of unicode strings */ typedef struct { uint32 ref_id; uint32 count; - UNISTR_ARRAY_EL *strings; -} UNISTR_ARRAY; + UNISTR2_ARRAY_EL *strings; +} UNISTR2_ARRAY; /* DOM_RID2 - domain RID structure for ntlsa pipe */ typedef struct domrid2_info diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c index 2b65c67f15..d9d05299cb 100644 --- a/source3/rpc_client/cli_lsarpc.c +++ b/source3/rpc_client/cli_lsarpc.c @@ -1206,6 +1206,46 @@ done: return result; } +/* add account rights to an account. */ + +NTSTATUS cli_lsa_add_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, DOM_SID sid, + uint32 count, const char **privs_name) +{ + prs_struct qbuf, rbuf; + LSA_Q_ADD_ACCT_RIGHTS q; + LSA_R_ADD_ACCT_RIGHTS r; + NTSTATUS result; + + ZERO_STRUCT(q); + + /* 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_q_add_acct_rights(&q, pol, &sid, count, privs_name); + + if (!lsa_io_q_add_acct_rights("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, LSA_ADDACCTRIGHTS, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!lsa_io_r_add_acct_rights("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + if (!NT_STATUS_IS_OK(result = r.status)) + goto done; + +done: + + return result; +} #if 0 diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c index 7c9f74da37..ac0242b113 100644 --- a/source3/rpc_parse/parse_lsa.c +++ b/source3/rpc_parse/parse_lsa.c @@ -1519,6 +1519,9 @@ BOOL lsa_io_r_priv_get_dispname(const char *desc, LSA_R_PRIV_GET_DISPNAME *r_q, return True; } +/* + initialise a LSA_Q_ENUM_ACCOUNTS structure +*/ void init_lsa_q_enum_accounts(LSA_Q_ENUM_ACCOUNTS *trn, POLICY_HND *hnd, uint32 enum_context, uint32 pref_max_length) { memcpy(&trn->pol, hnd, sizeof(trn->pol)); @@ -1549,6 +1552,7 @@ BOOL lsa_io_q_enum_accounts(const char *desc, LSA_Q_ENUM_ACCOUNTS *q_q, prs_stru return True; } + /******************************************************************* Inits an LSA_R_ENUM_PRIVS structure. ********************************************************************/ @@ -2249,8 +2253,7 @@ void init_q_enum_acct_rights(LSA_Q_ENUM_ACCT_RIGHTS *q_q, DEBUG(5, ("init_q_enum_acct_rights\n")); q_q->pol = *hnd; - q_q->count = count; - q_q->sid = *sid; + init_dom_sid2(&q_q->sid, sid); } /******************************************************************* @@ -2258,6 +2261,7 @@ reads or writes a LSA_Q_ENUM_ACCT_RIGHTS structure. ********************************************************************/ BOOL lsa_io_q_enum_acct_rights(const char *desc, LSA_Q_ENUM_ACCT_RIGHTS *q_q, prs_struct *ps, int depth) { + if (q_q == NULL) return False; @@ -2267,10 +2271,7 @@ BOOL lsa_io_q_enum_acct_rights(const char *desc, LSA_Q_ENUM_ACCT_RIGHTS *q_q, pr if (!smb_io_pol_hnd("", &q_q->pol, ps, depth)) return False; - if(!prs_uint32("count ", ps, depth, &q_q->count)) - return False; - - if(!smb_io_dom_sid("sid", &q_q->sid, ps, depth)) + if(!smb_io_dom_sid2("sid", &q_q->sid, ps, depth)) return False; return True; @@ -2288,9 +2289,68 @@ BOOL lsa_io_r_enum_acct_rights(const char *desc, LSA_R_ENUM_ACCT_RIGHTS *r_c, pr if(!prs_uint32("count ", ps, depth, &r_c->count)) return False; - if(!smb_io_unistr_array("rights", &r_c->rights, ps, depth)) + if(!smb_io_unistr2_array("rights", &r_c->rights, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; + + if(!prs_ntstatus("status", ps, depth, &r_c->status)) return False; + return True; +} + + +/******************************************************************* + Inits an LSA_Q_ADD_ACCT_RIGHTS structure. +********************************************************************/ +void init_q_add_acct_rights(LSA_Q_ADD_ACCT_RIGHTS *q_q, + POLICY_HND *hnd, + DOM_SID *sid, + uint32 count, + const char **rights) +{ + DEBUG(5, ("init_q_add_acct_rights\n")); + + q_q->pol = *hnd; + init_dom_sid2(&q_q->sid, sid); + init_unistr2_array(&q_q->rights, count, rights); + q_q->count = 5; +} + + +/******************************************************************* +reads or writes a LSA_Q_ADD_ACCT_RIGHTS structure. +********************************************************************/ +BOOL lsa_io_q_add_acct_rights(const char *desc, LSA_Q_ADD_ACCT_RIGHTS *q_q, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "lsa_io_q_add_acct_rights"); + depth++; + + if (!smb_io_pol_hnd("", &q_q->pol, ps, depth)) + return False; + + if(!smb_io_dom_sid2("sid", &q_q->sid, ps, depth)) + return False; + + if(!prs_uint32("count", ps, depth, &q_q->rights.count)) + return False; + + if(!smb_io_unistr2_array("rights", &q_q->rights, ps, depth)) + return False; + + return True; +} + +/******************************************************************* +reads or writes a LSA_R_ENUM_ACCT_RIGHTS structure. +********************************************************************/ +BOOL lsa_io_r_add_acct_rights(const char *desc, LSA_R_ADD_ACCT_RIGHTS *r_c, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "lsa_io_r_add_acct_rights"); + depth++; + if(!prs_ntstatus("status", ps, depth, &r_c->status)) return False; diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c index 9d3bd6f28a..43d26a691d 100644 --- a/source3/rpc_parse/parse_misc.c +++ b/source3/rpc_parse/parse_misc.c @@ -216,6 +216,7 @@ BOOL smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth) if(!prs_uint8 ("sid_rev_num", ps, depth, &sid->sid_rev_num)) return False; + if(!prs_uint8 ("num_auths ", ps, depth, &sid->num_auths)) return False; @@ -1043,17 +1044,45 @@ BOOL smb_io_unistr2(const char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct * } +/* + initialise a UNISTR_ARRAY from a char** +*/ +BOOL init_unistr2_array(UNISTR2_ARRAY *array, + uint32 count, const char **strings) +{ + int i; + + array->count = count; + array->ref_id = count?1:0; + if (array->count == 0) { + return True; + } + + array->strings = (UNISTR2_ARRAY_EL *)talloc_zero(get_talloc_ctx(), count * sizeof(UNISTR2_ARRAY_EL)); + if (!array->strings) { + return False; + } + + for (i=0;i<count;i++) { + init_unistr2(&array->strings[i].string, strings[i], strlen(strings[i])); + array->strings[i].size = array->strings[i].string.uni_max_len*2; + array->strings[i].length = array->strings[i].size; + array->strings[i].ref_id = 1; + } + + return True; +} + /******************************************************************* - Reads or writes a UNISTR_ARRAY structure. + Reads or writes a UNISTR2_ARRAY structure. ********************************************************************/ -BOOL smb_io_unistr_array(const char *desc, UNISTR_ARRAY *array, prs_struct *ps, int depth) +BOOL smb_io_unistr2_array(const char *desc, UNISTR2_ARRAY *array, prs_struct *ps, int depth) { int i; + prs_debug(ps, depth, desc, "smb_io_unistr2_array"); depth++; - array->count = 0; - if(!prs_uint32("ref_id", ps, depth, &array->ref_id)) return False; @@ -1068,7 +1097,9 @@ BOOL smb_io_unistr_array(const char *desc, UNISTR_ARRAY *array, prs_struct *ps, return True; } - array->strings = talloc_zero(get_talloc_ctx(), array->count * sizeof(array->strings[0])); + if (UNMARSHALLING(ps)) { + array->strings = talloc_zero(get_talloc_ctx(), array->count * sizeof(array->strings[0])); + } if (! array->strings) { return False; } diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index decbc8e161..458bb67cd2 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -23,6 +23,41 @@ #include "includes.h" #include "rpcclient.h" +/* useful function to allow entering a name instead of a SID and + * looking it up automatically */ +static NTSTATUS name_to_sid(struct cli_state *cli, + TALLOC_CTX *mem_ctx, + DOM_SID *sid, const char *name) +{ + POLICY_HND pol; + uint32 *sid_types; + NTSTATUS result; + DOM_SID *sids; + + /* maybe its a raw SID */ + if (strncmp(name, "S-", 2) == 0 && + string_to_sid(sid, name)) { + return NT_STATUS_OK; + } + + result = cli_lsa_open_policy(cli, mem_ctx, True, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &pol); + if (!NT_STATUS_IS_OK(result)) + goto done; + + result = cli_lsa_lookup_names(cli, mem_ctx, &pol, 1, &name, &sids, &sid_types); + if (!NT_STATUS_IS_OK(result)) + goto done; + + cli_lsa_close(cli, mem_ctx, &pol); + + *sid = sids[0]; + +done: + return result; +} + /* Look up domain related information on a remote host */ static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli, @@ -499,6 +534,44 @@ static NTSTATUS cmd_lsa_enum_acct_rights(struct cli_state *cli, } +/* add some privileges to a SID via LsaAddAccountRights */ + +static NTSTATUS cmd_lsa_add_acct_rights(struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + POLICY_HND dom_pol; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + DOM_SID sid; + + if (argc < 3 ) { + printf("Usage: %s SID [rights...]\n", argv[0]); + return NT_STATUS_OK; + } + + result = name_to_sid(cli, mem_ctx, &sid, argv[1]); + if (!NT_STATUS_IS_OK(result)) + goto done; + + 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_add_account_rights(cli, mem_ctx, &dom_pol, sid, + argc-2, argv+2); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + done: + return result; +} + + /* Get a privilege value given its name */ static NTSTATUS cmd_lsa_lookupprivvalue(struct cli_state *cli, @@ -586,6 +659,7 @@ struct cmd_set lsarpc_commands[] = { { "lsaenumsid", cmd_lsa_enum_sids, PI_LSARPC, "Enumerate the LSA SIDS", "" }, { "lsaenumprivsaccount", cmd_lsa_enum_privsaccounts, PI_LSARPC, "Enumerate the privileges of an SID", "" }, { "lsaenumacctrights", cmd_lsa_enum_acct_rights, PI_LSARPC, "Enumerate the rights of an SID", "" }, + { "lsaaddacctrights", cmd_lsa_add_acct_rights, PI_LSARPC, "Add rights to an account", "" }, { "lsalookupprivvalue", cmd_lsa_lookupprivvalue, PI_LSARPC, "Get a privilege value given its name", "" }, { "lsaquerysecobj", cmd_lsa_query_secobj, PI_LSARPC, "Query LSA security object", "" }, |