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/rpc_server/srv_lsa.c | 190 +++++++++++++++++++++++++++++++++++ source3/rpc_server/srv_lsa_nt.c | 217 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 406 insertions(+), 1 deletion(-) (limited to 'source3/rpc_server') 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