From 0a33cb45c1a30143d3587b102b0cde31158d7788 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Mon, 9 Jul 2001 18:32:54 +0000 Subject: implement: LSA_ENUM_PRIVS LSA_PRIV_GET_DISPNAME LSA_ENUM_ACCOUNTS LSA_OPENACCOUNT LSA_ENUMPRIVSACCOUNT LSA_GETSYSTEMACCOUNT It's a work in progress. nobody should expect it to work J.F. (This used to be commit 3056357cd8d4b2460f73ba8a8931a143f07fa2a6) --- source3/include/rpc_lsa.h | 152 ++++++++++++- source3/rpc_parse/parse_lsa.c | 476 ++++++++++++++++++++++++++++++++++++++++ source3/rpc_server/srv_lsa.c | 190 ++++++++++++++++ source3/rpc_server/srv_lsa_nt.c | 217 +++++++++++++++++- 4 files changed, 1032 insertions(+), 3 deletions(-) diff --git a/source3/include/rpc_lsa.h b/source3/include/rpc_lsa.h index 1a6e178068..9cd9929aa9 100644 --- a/source3/include/rpc_lsa.h +++ b/source3/include/rpc_lsa.h @@ -41,13 +41,19 @@ enum SID_NAME_USE /* ntlsa pipe */ #define LSA_CLOSE 0x00 +#define LSA_ENUM_PRIVS 0x02 +#define LSA_OPENPOLICY 0x06 #define LSA_QUERYINFOPOLICY 0x07 +#define LSA_ENUM_ACCOUNTS 0x0b #define LSA_ENUMTRUSTDOM 0x0d #define LSA_LOOKUPNAMES 0x0e #define LSA_LOOKUPSIDS 0x0f -#define LSA_OPENPOLICY 0x06 -#define LSA_OPENPOLICY2 0x2c +#define LSA_OPENACCOUNT 0x11 +#define LSA_ENUMPRIVSACCOUNT 0x12 +#define LSA_GETSYSTEMACCOUNT 0x17 #define LSA_OPENSECRET 0x1C +#define LSA_PRIV_GET_DISPNAME 0x21 +#define LSA_OPENPOLICY2 0x2c #define LSA_UNK_GET_CONNUSER 0x2d /* LsaGetConnectedCredentials ? */ /* XXXX these are here to get a compile! */ @@ -381,6 +387,72 @@ typedef struct lsa_r_open_secret uint32 status; } LSA_R_OPEN_SECRET; +typedef struct lsa_enum_priv_entry +{ + UNIHDR hdr_name; + uint32 luid_low; + uint32 luid_high; + UNISTR2 name; + +} LSA_PRIV_ENTRY; + +/* LSA_Q_ENUM_PRIVS - LSA enum privileges */ +typedef struct lsa_q_enum_privs +{ + POLICY_HND pol; /* policy handle */ + uint32 enum_context; + uint32 pref_max_length; +} LSA_Q_ENUM_PRIVS; + +typedef struct lsa_r_enum_privs +{ + uint32 enum_context; + uint32 count; + uint32 ptr; + uint32 count1; + + LSA_PRIV_ENTRY *privs; + + uint32 status; +} LSA_R_ENUM_PRIVS; + +/* LSA_Q_PRIV_GET_DISPNAME - LSA get privilege display name */ +typedef struct lsa_q_priv_get_dispname +{ + POLICY_HND pol; /* policy handle */ + UNIHDR hdr_name; + UNISTR2 name; + uint16 lang_id; + uint16 lang_id_sys; +} LSA_Q_PRIV_GET_DISPNAME; + +typedef struct lsa_r_priv_get_dispname +{ + uint32 ptr_info; + UNIHDR hdr_desc; + UNISTR2 desc; + /* Don't align ! */ + uint16 lang_id; + /* align */ + uint32 status; +} LSA_R_PRIV_GET_DISPNAME; + +/* LSA_Q_ENUM_ACCOUNTS */ +typedef struct lsa_q_enum_accounts +{ + POLICY_HND pol; /* policy handle */ + uint32 enum_context; + uint32 pref_max_length; +} LSA_Q_ENUM_ACCOUNTS; + +/* LSA_R_ENUM_ACCOUNTS */ +typedef struct lsa_r_enum_accounts +{ + uint32 enum_context; + LSA_SID_ENUM sids; + uint32 status; +} LSA_R_ENUM_ACCOUNTS; + /* LSA_Q_UNK_GET_CONNUSER - gets username\domain of connected user called when "Take Ownership" is clicked -SK */ typedef struct lsa_q_unk_get_connuser @@ -408,4 +480,80 @@ typedef struct lsa_r_unk_get_connuser uint32 status; } LSA_R_UNK_GET_CONNUSER; + +typedef struct lsa_q_openaccount +{ + POLICY_HND pol; /* policy handle */ + DOM_SID2 sid; + uint32 access; /* desired access */ +} LSA_Q_OPENACCOUNT; + +typedef struct lsa_r_openaccount +{ + POLICY_HND pol; /* policy handle */ + uint32 status; +} LSA_R_OPENACCOUNT; + +typedef struct lsa_q_enumprivsaccount +{ + POLICY_HND pol; /* policy handle */ +} LSA_Q_ENUMPRIVSACCOUNT; + + +typedef struct LUID +{ + uint32 low; + uint32 high; +} LUID; + +typedef struct LUID_ATTR +{ + LUID luid; + uint32 attr; +} LUID_ATTR ; + +typedef struct privilege_set +{ + uint32 count; + uint32 control; + LUID_ATTR *set; +} PRIVILEGE_SET; + +typedef struct lsa_r_enumprivsaccount +{ + uint32 ptr; + uint32 count; + PRIVILEGE_SET set; + uint32 status; +} LSA_R_ENUMPRIVSACCOUNT; + +typedef struct lsa_q_getsystemaccount +{ + POLICY_HND pol; /* policy handle */ +} LSA_Q_GETSYSTEMACCOUNT; + +typedef struct lsa_r_getsystemaccount +{ + uint32 access; + uint32 status; +} LSA_R_GETSYSTEMACCOUNT; + + #endif /* _RPC_LSA_H */ +/* + +opnum 11: opensid: query: handle du domaine, sid du user +reply: handle, status + +opnum 12: getlistofprivs: query: handle du user +reply: ptr, nombre, nombre, tableau de 3 uint32: flag+priv.low+priv.high +uint32 0, status + +opnum 17: ?? query: handle +reply: uint32 + status + + +*/ + + + diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c index 5abcfb9eef..d07c91e137 100644 --- a/source3/rpc_parse/parse_lsa.c +++ b/source3/rpc_parse/parse_lsa.c @@ -1282,6 +1282,263 @@ BOOL lsa_io_r_open_secret(char *desc, LSA_R_OPEN_SECRET *r_c, prs_struct *ps, in return True; } +/******************************************************************* +reads or writes a structure. +********************************************************************/ +BOOL lsa_io_q_enum_privs(char *desc, LSA_Q_ENUM_PRIVS *q_q, prs_struct *ps, int depth) +{ + if (q_q == NULL) + return False; + + prs_debug(ps, depth, desc, "lsa_io_q_enum_privs"); + depth++; + + if (!smb_io_pol_hnd("", &q_q->pol, ps, depth)) + return False; + + if(!prs_uint32("enum_context ", ps, depth, &q_q->enum_context)) + return False; + if(!prs_uint32("pref_max_length", ps, depth, &q_q->pref_max_length)) + return False; + + return True; +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +static BOOL lsa_io_priv_entries(char *desc, LSA_PRIV_ENTRY *entries, uint32 count, prs_struct *ps, int depth) +{ + uint32 i; + + if (entries == NULL) + return False; + + prs_debug(ps, depth, desc, "lsa_io_priv_entries"); + depth++; + + if(!prs_align(ps)) + return False; + + for (i = 0; i < count; i++) { + if (!smb_io_unihdr("", &entries[i].hdr_name, ps, depth)) + return False; + if(!prs_uint32("luid_low ", ps, depth, &entries[i].luid_low)) + return False; + if(!prs_uint32("luid_high", ps, depth, &entries[i].luid_high)) + return False; + } + + for (i = 0; i < count; i++) + if (!smb_io_unistr2("", &entries[i].name, entries[i].hdr_name.buffer, ps, depth)) + return False; + + return True; +} + +/******************************************************************* + Inits an LSA_R_ENUM_PRIVS structure. +********************************************************************/ + +void init_lsa_r_enum_privs(LSA_R_ENUM_PRIVS *r_u, uint32 enum_context, + uint32 count, LSA_PRIV_ENTRY *entries) +{ + DEBUG(5, ("init_lsa_r_enum_privs\n")); + + r_u->enum_context=enum_context; + r_u->count=count; + + if (entries!=NULL) { + r_u->ptr=1; + r_u->count1=count; + r_u->privs=entries; + } else { + r_u->ptr=0; + r_u->count1=0; + r_u->privs=NULL; + } +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +BOOL lsa_io_r_enum_privs(char *desc, LSA_R_ENUM_PRIVS *r_q, prs_struct *ps, int depth) +{ + if (r_q == NULL) + return False; + + prs_debug(ps, depth, desc, "lsa_io_r_enum_privs"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("enum_context", ps, depth, &r_q->enum_context)) + return False; + if(!prs_uint32("count", ps, depth, &r_q->count)) + return False; + if(!prs_uint32("ptr", ps, depth, &r_q->ptr)) + return False; + + if (r_q->ptr) { + if(!prs_uint32("count1", ps, depth, &r_q->count1)) + return False; + + if (!lsa_io_priv_entries("", r_q->privs, r_q->count1, ps, depth)) + return False; + } + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("status", ps, depth, &r_q->status)) + return False; + + return True; +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +BOOL lsa_io_q_priv_get_dispname(char *desc, LSA_Q_PRIV_GET_DISPNAME *q_q, prs_struct *ps, int depth) +{ + if (q_q == NULL) + return False; + + prs_debug(ps, depth, desc, "lsa_io_q_priv_get_dispname"); + depth++; + + if(!prs_align(ps)) + return False; + + if (!smb_io_pol_hnd("", &q_q->pol, ps, depth)) + return False; + + if (!smb_io_unihdr("hdr_name", &q_q->hdr_name, ps, depth)) + return False; + + if (!smb_io_unistr2("name", &q_q->name, q_q->hdr_name.buffer, ps, depth)) + return False; + + if(!prs_uint16("lang_id ", ps, depth, &q_q->lang_id)) + return False; + if(!prs_uint16("lang_id_sys", ps, depth, &q_q->lang_id_sys)) + return False; + + return True; +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +BOOL lsa_io_r_priv_get_dispname(char *desc, LSA_R_PRIV_GET_DISPNAME *r_q, prs_struct *ps, int depth) +{ + if (r_q == NULL) + return False; + + prs_debug(ps, depth, desc, "lsa_io_r_priv_get_dispname"); + depth++; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("ptr_info", ps, depth, &r_q->ptr_info)) + return False; + + if (r_q->ptr_info){ + if (!smb_io_unihdr("hdr_name", &r_q->hdr_desc, ps, depth)) + return False; + + if (!smb_io_unistr2("desc", &r_q->desc, r_q->hdr_desc.buffer, ps, depth)) + return False; + } +/* + if(!prs_align(ps)) + return False; +*/ + if(!prs_uint16("lang_id", ps, depth, &r_q->lang_id)) + return False; + + if(!prs_align(ps)) + return False; + if(!prs_uint32("status", ps, depth, &r_q->status)) + return False; + + return True; +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +BOOL lsa_io_q_enum_accounts(char *desc, LSA_Q_ENUM_ACCOUNTS *q_q, prs_struct *ps, int depth) +{ + if (q_q == NULL) + return False; + + prs_debug(ps, depth, desc, "lsa_io_q_enum_accounts"); + depth++; + + if (!smb_io_pol_hnd("", &q_q->pol, ps, depth)) + return False; + + if(!prs_uint32("enum_context ", ps, depth, &q_q->enum_context)) + return False; + if(!prs_uint32("pref_max_length", ps, depth, &q_q->pref_max_length)) + return False; + + return True; +} + +/******************************************************************* + Inits an LSA_R_ENUM_PRIVS structure. +********************************************************************/ + +void init_lsa_r_enum_accounts(LSA_R_ENUM_ACCOUNTS *r_u, uint32 enum_context) +{ + DEBUG(5, ("init_lsa_r_enum_accounts\n")); + + r_u->enum_context=enum_context; + if (r_u->enum_context!=0) { + r_u->sids.num_entries=enum_context; + r_u->sids.ptr_sid_enum=1; + r_u->sids.num_entries2=enum_context; + } else { + r_u->sids.num_entries=0; + r_u->sids.ptr_sid_enum=0; + r_u->sids.num_entries2=0; + } +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +BOOL lsa_io_r_enum_accounts(char *desc, LSA_R_ENUM_ACCOUNTS *r_q, prs_struct *ps, int depth) +{ + if (r_q == NULL) + return False; + + prs_debug(ps, depth, desc, "lsa_io_r_enum_accounts"); + depth++; + + if (!prs_align(ps)) + return False; + + if(!prs_uint32("enum_context", ps, depth, &r_q->enum_context)) + return False; + + if (!lsa_io_sid_enum("sids", &r_q->sids, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + + if(!prs_uint32("status", ps, depth, &r_q->status)) + return False; + + return True; +} + + /******************************************************************* Reads or writes an LSA_Q_UNK_GET_CONNUSER structure. ********************************************************************/ @@ -1351,3 +1608,222 @@ BOOL lsa_io_r_unk_get_connuser(char *desc, LSA_R_UNK_GET_CONNUSER *r_c, prs_stru return True; } + +/******************************************************************* + Reads or writes an LSA_Q_OPENACCOUNT structure. +********************************************************************/ + +BOOL lsa_io_q_open_account(char *desc, LSA_Q_OPENACCOUNT *r_c, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "lsa_io_q_open_account"); + depth++; + + if(!prs_align(ps)) + return False; + + 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 */ + return False; + + if(!prs_uint32("access", ps, depth, &r_c->access)) + return False; + + return True; +} + +/******************************************************************* + Reads or writes an LSA_R_OPENACCOUNT structure. +********************************************************************/ + +BOOL lsa_io_r_open_account(char *desc, LSA_R_OPENACCOUNT *r_c, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "lsa_io_r_open_account"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!smb_io_pol_hnd("pol", &r_c->pol, ps, depth)) + return False; + + if(!prs_uint32("status", ps, depth, &r_c->status)) + return False; + + return True; +} + + +/******************************************************************* + Reads or writes an LSA_Q_ENUMPRIVSACCOUNT structure. +********************************************************************/ + +BOOL lsa_io_q_enum_privsaccount(char *desc, LSA_Q_ENUMPRIVSACCOUNT *r_c, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "lsa_io_q_enum_privsaccount"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!smb_io_pol_hnd("pol", &r_c->pol, ps, depth)) + return False; + + return True; +} + +/******************************************************************* + Reads or writes an LUID structure. +********************************************************************/ + +BOOL lsa_io_luid(char *desc, LUID *r_c, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "lsa_io_luid"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("low", ps, depth, &r_c->low)) + return False; + + if(!prs_uint32("high", ps, depth, &r_c->high)) + return False; + + return True; +} + +/******************************************************************* + Reads or writes an LUID_ATTR structure. +********************************************************************/ + +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++; + + if(!prs_align(ps)) + return False; + + if (!lsa_io_luid(desc, &r_c->luid, ps, depth)) + return False; + + if(!prs_uint32("attr", ps, depth, &r_c->attr)) + return False; + + return True; +} + +/******************************************************************* + Reads or writes an PRIVILEGE_SET structure. +********************************************************************/ + +BOOL lsa_io_privilege_set(char *desc, PRIVILEGE_SET *r_c, prs_struct *ps, int depth) +{ + uint32 i; + + prs_debug(ps, depth, desc, "lsa_io_privilege_set"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("count", ps, depth, &r_c->count)) + return False; + if(!prs_uint32("control", ps, depth, &r_c->control)) + return False; + + for (i=0; icount; i++) { + if (!lsa_io_luid_attr(desc, &r_c->set[i], ps, depth)) + return False; + } + + return True; +} + +void init_lsa_r_enum_privsaccount(LSA_R_ENUMPRIVSACCOUNT *r_u, LUID_ATTR *set, uint32 count, uint32 control) +{ + r_u->ptr=1; + r_u->count=count; + r_u->set.set=set; + r_u->set.count=count; + r_u->set.control=control; +} + +/******************************************************************* + Reads or writes an LSA_R_ENUMPRIVSACCOUNT structure. +********************************************************************/ + +BOOL lsa_io_r_enum_privsaccount(char *desc, LSA_R_ENUMPRIVSACCOUNT *r_c, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "lsa_io_r_enum_privsaccount"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("ptr", ps, depth, &r_c->ptr)) + return False; + + if (r_c->ptr!=0) { + if(!prs_uint32("count", ps, depth, &r_c->count)) + return False; + + /* malloc memory if unmarshalling here */ + + if(!lsa_io_privilege_set(desc, &r_c->set, ps, depth)) + return False; + } + + if(!prs_uint32("status", ps, depth, &r_c->status)) + return False; + + return True; +} + + + +/******************************************************************* + Reads or writes an LSA_Q_GETSYSTEMACCOUNTstructure. +********************************************************************/ + +BOOL lsa_io_q_getsystemaccount(char *desc, LSA_Q_GETSYSTEMACCOUNT *r_c, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "lsa_io_q_getsystemaccount"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!smb_io_pol_hnd("pol", &r_c->pol, ps, depth)) + return False; + + return True; +} + +/******************************************************************* + Reads or writes an LSA_R_GETSYSTEMACCOUNTstructure. +********************************************************************/ + +BOOL lsa_io_r_getsystemaccount(char *desc, LSA_R_GETSYSTEMACCOUNT *r_c, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "lsa_io_r_getsystemaccount"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("access", ps, depth, &r_c->access)) + return False; + + if(!prs_uint32("status", ps, depth, &r_c->status)) + return False; + + return True; +} + + + + + diff --git a/source3/rpc_server/srv_lsa.c b/source3/rpc_server/srv_lsa.c index 005398924e..9c934f5023 100644 --- a/source3/rpc_server/srv_lsa.c +++ b/source3/rpc_server/srv_lsa.c @@ -268,6 +268,96 @@ static BOOL api_lsa_open_secret(pipes_struct *p) return True; } +/*************************************************************************** + api_lsa_open_secret. + ***************************************************************************/ + +static BOOL api_lsa_enum_privs(pipes_struct *p) +{ + LSA_Q_ENUM_PRIVS q_u; + LSA_R_ENUM_PRIVS r_u; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + if(!lsa_io_q_enum_privs("", &q_u, data, 0)) { + DEBUG(0,("api_lsa_enum_privs: failed to unmarshall LSA_Q_ENUM_PRIVS.\n")); + return False; + } + + r_u.status = _lsa_enum_privs(p, &q_u, &r_u); + + /* store the response in the SMB stream */ + if(!lsa_io_r_enum_privs("", &r_u, rdata, 0)) { + DEBUG(0,("api_lsa_enum_privs: Failed to marshall LSA_R_ENUM_PRIVS.\n")); + return False; + } + + return True; +} + +/*************************************************************************** + api_lsa_open_secret. + ***************************************************************************/ + +static BOOL api_lsa_priv_get_dispname(pipes_struct *p) +{ + LSA_Q_PRIV_GET_DISPNAME q_u; + LSA_R_PRIV_GET_DISPNAME r_u; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + if(!lsa_io_q_priv_get_dispname("", &q_u, data, 0)) { + DEBUG(0,("api_lsa_priv_get_dispname: failed to unmarshall LSA_Q_PRIV_GET_DISPNAME.\n")); + return False; + } + + r_u.status = _lsa_priv_get_dispname(p, &q_u, &r_u); + + /* store the response in the SMB stream */ + if(!lsa_io_r_priv_get_dispname("", &r_u, rdata, 0)) { + DEBUG(0,("api_lsa_priv_get_dispname: Failed to marshall LSA_R_PRIV_GET_DISPNAME.\n")); + return False; + } + + return True; +} + +/*************************************************************************** + api_lsa_open_secret. + ***************************************************************************/ + +static BOOL api_lsa_enum_accounts(pipes_struct *p) +{ + LSA_Q_ENUM_ACCOUNTS q_u; + LSA_R_ENUM_ACCOUNTS r_u; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + if(!lsa_io_q_enum_accounts("", &q_u, data, 0)) { + DEBUG(0,("api_lsa_enum_accounts: failed to unmarshall LSA_Q_ENUM_ACCOUNTS.\n")); + return False; + } + + r_u.status = _lsa_enum_accounts(p, &q_u, &r_u); + + /* store the response in the SMB stream */ + if(!lsa_io_r_enum_accounts("", &r_u, rdata, 0)) { + DEBUG(0,("api_lsa_enum_accounts: Failed to marshall LSA_R_ENUM_ACCOUNTS.\n")); + return False; + } + + return True; +} + /*************************************************************************** api_lsa_UNK_GET_CONNUSER ***************************************************************************/ @@ -299,6 +389,100 @@ static BOOL api_lsa_unk_get_connuser(pipes_struct *p) return True; } +/*************************************************************************** + api_lsa_open_user + ***************************************************************************/ + +static BOOL api_lsa_open_account(pipes_struct *p) +{ + LSA_Q_OPENACCOUNT q_u; + LSA_R_OPENACCOUNT r_u; + + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + if(!lsa_io_q_open_account("", &q_u, data, 0)) { + DEBUG(0,("api_lsa_open_account: failed to unmarshall LSA_Q_OPENACCOUNT.\n")); + return False; + } + + r_u.status = _lsa_open_account(p, &q_u, &r_u); + + /* store the response in the SMB stream */ + if(!lsa_io_r_open_account("", &r_u, rdata, 0)) { + DEBUG(0,("api_lsa_open_account: Failed to marshall LSA_R_OPENACCOUNT.\n")); + return False; + } + + return True; +} + +/*************************************************************************** + api_lsa_get_privs + ***************************************************************************/ + +static BOOL api_lsa_enum_privsaccount(pipes_struct *p) +{ + LSA_Q_ENUMPRIVSACCOUNT q_u; + LSA_R_ENUMPRIVSACCOUNT r_u; + + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + if(!lsa_io_q_enum_privsaccount("", &q_u, data, 0)) { + DEBUG(0,("api_lsa_enum_privsaccount: failed to unmarshall LSA_Q_ENUMPRIVSACCOUNT.\n")); + return False; + } + + r_u.status = _lsa_enum_privsaccount(p, &q_u, &r_u); + + /* store the response in the SMB stream */ + if(!lsa_io_r_enum_privsaccount("", &r_u, rdata, 0)) { + DEBUG(0,("api_lsa_enum_privsaccount: Failed to marshall LSA_R_ENUMPRIVSACCOUNT.\n")); + return False; + } + + return True; +} + +/*************************************************************************** + api_lsa_getsystemaccount + ***************************************************************************/ + +static BOOL api_lsa_getsystemaccount(pipes_struct *p) +{ + LSA_Q_GETSYSTEMACCOUNT q_u; + LSA_R_GETSYSTEMACCOUNT r_u; + + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + if(!lsa_io_q_getsystemaccount("", &q_u, data, 0)) { + DEBUG(0,("api_lsa_getsystemaccount: failed to unmarshall LSA_Q_GETSYSTEMACCOUNT.\n")); + return False; + } + + r_u.status = _lsa_getsystemaccount(p, &q_u, &r_u); + + /* store the response in the SMB stream */ + if(!lsa_io_r_getsystemaccount("", &r_u, rdata, 0)) { + DEBUG(0,("api_lsa_getsystemaccount: Failed to marshall LSA_R_GETSYSTEMACCOUNT.\n")); + return False; + } + + return True; +} + + /*************************************************************************** \PIPE\ntlsa commands ***************************************************************************/ @@ -313,7 +497,13 @@ static struct api_struct api_lsa_cmds[] = { "LSA_OPENSECRET" , LSA_OPENSECRET , api_lsa_open_secret }, { "LSA_LOOKUPSIDS" , LSA_LOOKUPSIDS , api_lsa_lookup_sids }, { "LSA_LOOKUPNAMES" , LSA_LOOKUPNAMES , api_lsa_lookup_names }, + { "LSA_ENUM_PRIVS" , LSA_ENUM_PRIVS , api_lsa_enum_privs }, + { "LSA_PRIV_GET_DISPNAME",LSA_PRIV_GET_DISPNAME,api_lsa_priv_get_dispname}, + { "LSA_ENUM_ACCOUNTS" , LSA_ENUM_ACCOUNTS , api_lsa_enum_accounts }, { "LSA_UNK_GET_CONNUSER", LSA_UNK_GET_CONNUSER, api_lsa_unk_get_connuser}, + { "LSA_OPENACCOUNT" , LSA_OPENACCOUNT , api_lsa_open_account }, + { "LSA_ENUMPRIVSACCOUNT", LSA_ENUMPRIVSACCOUNT, api_lsa_enum_privsaccount}, + { "LSA_GETSYSTEMACCOUNT", LSA_GETSYSTEMACCOUNT, api_lsa_getsystemaccount}, { NULL , 0 , NULL } }; diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index cd97dfc6d1..85bab7d4b0 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -30,6 +30,23 @@ extern int DEBUGLEVEL; extern DOM_SID global_sam_sid; extern fstring global_myworkgroup; extern pstring global_myname; +extern PRIVS privs[]; + +struct lsa_info { + DOM_SID sid; + uint32 access; +}; + +/******************************************************************* + Function to free the per handle data. + ********************************************************************/ + +static void free_lsa_info(void *ptr) +{ + struct lsa_info *lsa = (struct lsa_info *)ptr; + + safe_free(lsa); +} /*************************************************************************** Init dom_query @@ -128,7 +145,7 @@ static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2, /* Split name into domain and user component */ - rpcstr_pull(full_name, &name[i], sizeof(full_name), -1, 0); + unistr2_to_ascii(full_name, &name[i], sizeof(full_name)); split_domain_name(full_name, dom_name, user); /* Lookup name */ @@ -511,6 +528,116 @@ uint32 _lsa_open_secret(pipes_struct *p, LSA_Q_OPEN_SECRET *q_u, LSA_R_OPEN_SECR return NT_STATUS_OBJECT_NAME_NOT_FOUND; } +/*************************************************************************** +_lsa_enum_privs. + ***************************************************************************/ + +uint32 _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIVS *r_u) +{ + uint32 i; + + uint32 enum_context=q_u->enum_context; + LSA_PRIV_ENTRY *entry; + LSA_PRIV_ENTRY *entries; + + if (!find_policy_by_hnd(p, &q_u->pol, NULL)) + return NT_STATUS_INVALID_HANDLE; + + if (enum_context >= PRIV_ALL_INDEX) + return 0x8000001A; + + entries = (LSA_PRIV_ENTRY *)talloc_zero(p->mem_ctx, sizeof(LSA_PRIV_ENTRY) * (PRIV_ALL_INDEX-enum_context)); + if (entries==NULL) + return NT_STATUS_NO_MEMORY; + + entry = entries; + for (i = 0; i < PRIV_ALL_INDEX-enum_context; i++, entry++) { + init_uni_hdr(&entry->hdr_name, strlen(privs[i+1-enum_context].priv)); + init_unistr2(&entry->name, privs[i+1-enum_context].priv, strlen(privs[i+1-enum_context].priv) ); + entry->luid_low = privs[i+1-enum_context].se_priv; + entry->luid_high = 1; + } + + init_lsa_r_enum_privs(r_u, i+enum_context, PRIV_ALL_INDEX-enum_context, entries); + + return NT_STATUS_NO_PROBLEMO; +} + +/*************************************************************************** +_lsa_priv_get_dispname. + ***************************************************************************/ + +uint32 _lsa_priv_get_dispname(pipes_struct *p, LSA_Q_PRIV_GET_DISPNAME *q_u, LSA_R_PRIV_GET_DISPNAME *r_u) +{ + fstring name_asc; + fstring desc_asc; + int i; + + if (!find_policy_by_hnd(p, &q_u->pol, NULL)) + return NT_STATUS_INVALID_HANDLE; + + unistr2_to_ascii(name_asc, &q_u->name, sizeof(name_asc)); + + DEBUG(0,("_lsa_priv_get_dispname: %s", name_asc)); + + for (i=1; privs[i].se_priv!=SE_PRIV_ALL; i++) { + if ( strcmp(name_asc, privs[i].priv)) { + + fstrcpy(desc_asc, privs[i].description); + + } + } + DEBUG(0,(": %s\n", desc_asc)); + + init_uni_hdr(&r_u->hdr_desc, strlen(desc_asc)); + init_unistr2(&r_u->desc, desc_asc, strlen(desc_asc) ); + + r_u->ptr_info=0xdeadbeef; + r_u->lang_id=q_u->lang_id; + + return NT_STATUS_NO_PROBLEMO; +} + +/*************************************************************************** +_lsa_enum_accounts. + ***************************************************************************/ + +uint32 _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENUM_ACCOUNTS *r_u) +{ + GROUP_MAP *map=NULL; + int num_entries=0; + LSA_SID_ENUM *sids=&r_u->sids; + int i=0,j=0; + + if (!find_policy_by_hnd(p, &q_u->pol, NULL)) + return NT_STATUS_INVALID_HANDLE; + + /* get the list of mapped groups (domain, local, builtin) */ + if(!enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries, ENUM_ONLY_MAPPED)) + return NT_STATUS_NOPROBLEMO; + + sids->ptr_sid = (uint32 *)talloc_zero(p->mem_ctx, (num_entries-q_u->enum_context)*sizeof(uint32)); + sids->sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, (num_entries-q_u->enum_context)*sizeof(DOM_SID2)); + + if (sids->ptr_sid==NULL || sids->sid==NULL) { + safe_free(map); + return NT_STATUS_NO_MEMORY; + } + + for (i=q_u->enum_context, j=0; istatus; } + +/*************************************************************************** + + ***************************************************************************/ + +uint32 _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENACCOUNT *r_u) +{ + struct lsa_info *info; + + r_u->status = NT_STATUS_NOPROBLEMO; + + /* find the connection policy handle. */ + if (!find_policy_by_hnd(p, &q_u->pol, NULL)) + return NT_STATUS_INVALID_HANDLE; + + /* associate the user/group SID with the (unique) handle. */ + if ((info = (struct lsa_info *)malloc(sizeof(struct lsa_info))) == NULL) + return NT_STATUS_NO_MEMORY; + + ZERO_STRUCTP(info); + info->sid = q_u->sid.sid; + info->access = q_u->access; + + /* get a (unique) handle. open a policy on it. */ + if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info)) + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + + return r_u->status; +} + +/*************************************************************************** + + ***************************************************************************/ + +uint32 _lsa_enum_privsaccount(pipes_struct *p, LSA_Q_ENUMPRIVSACCOUNT *q_u, LSA_R_ENUMPRIVSACCOUNT *r_u) +{ + struct lsa_info *info=NULL; + GROUP_MAP map; + int num_entries=0; + uint32 count=0; + int i=0; + + LUID_ATTR *set=NULL; + + r_u->status = NT_STATUS_NOPROBLEMO; + + /* find the connection policy handle. */ + if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) + return NT_STATUS_INVALID_HANDLE; + + if (!get_group_map_from_sid(info->sid, &map)) + return NT_STATUS_NO_SUCH_GROUP; + + for (i=1; privs[i].se_priv!=SE_PRIV_ALL; i++) { + if ( (map.privilege & privs[i].se_priv) == privs[i].se_priv) { + + set=(LUID_ATTR *)talloc_realloc(p->mem_ctx, set, (count+1)*sizeof(LUID_ATTR)); + + set[count].luid.low=privs[i].se_priv; + set[count].luid.high=1; + set[count].attr=0; + + count++; + + } + } + + init_lsa_r_enum_privsaccount(r_u, set, count, 0); + + return r_u->status; +} + +/*************************************************************************** + + ***************************************************************************/ + +uint32 _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA_R_GETSYSTEMACCOUNT *r_u) +{ + r_u->status = NT_STATUS_NOPROBLEMO; + + /* find the connection policy handle. */ + if (!find_policy_by_hnd(p, &q_u->pol, NULL)) + return NT_STATUS_INVALID_HANDLE; + + r_u->access=3; + + return r_u->status; +} -- cgit