diff options
author | Jean-François Micouleau <jfm@samba.org> | 2001-12-17 23:03:23 +0000 |
---|---|---|
committer | Jean-François Micouleau <jfm@samba.org> | 2001-12-17 23:03:23 +0000 |
commit | 6e76486505287124eb62e32c4387a9608364a568 (patch) | |
tree | bfe60b710913ba820a0e0490dfccf41bbd661d51 /source3 | |
parent | a081ad3daed709859eacf607cf120f065bbcf0a0 (diff) | |
download | samba-6e76486505287124eb62e32c4387a9608364a568.tar.gz samba-6e76486505287124eb62e32c4387a9608364a568.tar.bz2 samba-6e76486505287124eb62e32c4387a9608364a568.zip |
there is no unknown field in LSA_SEC_QOS
some cleanup of the lsa_open_policy and lsa_open_policy2 parser. the
length fields are not correct but that's what NT send. We don't anymore
underflow or overflow the decoding.
added the domain admins group to the default SD.
we are now checking the desired access flag in the lsa_open_policy_X()
calls and in most functions also.
J.F.
(This used to be commit a217c4e4ff4d13122703d22258792fe5e8e9f02f)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/rpc_lsa.h | 1 | ||||
-rw-r--r-- | source3/libsmb/cli_lsarpc.c | 4 | ||||
-rw-r--r-- | source3/rpc_parse/parse_lsa.c | 34 | ||||
-rw-r--r-- | source3/rpc_server/srv_lsa_nt.c | 275 |
4 files changed, 225 insertions, 89 deletions
diff --git a/source3/include/rpc_lsa.h b/source3/include/rpc_lsa.h index 5ed321230e..4f72aa1316 100644 --- a/source3/include/rpc_lsa.h +++ b/source3/include/rpc_lsa.h @@ -131,7 +131,6 @@ typedef struct seq_qos_info uint16 sec_imp_level; /* 0x02 - impersonation level */ uint8 sec_ctxt_mode; /* 0x01 - context tracking mode */ uint8 effective_only; /* 0x00 - effective only */ - uint32 unknown; /* 0x2000 0000 - not known */ } LSA_SEC_QOS; diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index ff4c4dfe30..0720cadfbd 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -75,7 +75,7 @@ NTSTATUS cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Initialise input parameters */ if (sec_qos) { - init_lsa_sec_qos(&qos, 2, 1, 0, des_access); + init_lsa_sec_qos(&qos, 2, 1, 0); init_q_open_pol(&q, '\\', 0, des_access, &qos); } else { init_q_open_pol(&q, '\\', 0, des_access, NULL); @@ -131,7 +131,7 @@ NTSTATUS cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Initialise input parameters */ if (sec_qos) { - init_lsa_sec_qos(&qos, 2, 1, 0, des_access); + init_lsa_sec_qos(&qos, 2, 1, 0); init_q_open_pol2(&q, cli->clnt_name_slash, 0, des_access, &qos); } else { diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c index 6aa696369a..12b0ec2e16 100644 --- a/source3/rpc_parse/parse_lsa.c +++ b/source3/rpc_parse/parse_lsa.c @@ -138,8 +138,7 @@ static BOOL lsa_io_dom_r_ref(char *desc, DOM_R_REF *r_r, prs_struct *ps, Inits an LSA_SEC_QOS structure. ********************************************************************/ -void init_lsa_sec_qos(LSA_SEC_QOS *qos, uint16 imp_lev, uint8 ctxt, uint8 eff, - uint32 unknown) +void init_lsa_sec_qos(LSA_SEC_QOS *qos, uint16 imp_lev, uint8 ctxt, uint8 eff) { DEBUG(5, ("init_lsa_sec_qos\n")); @@ -147,7 +146,6 @@ void init_lsa_sec_qos(LSA_SEC_QOS *qos, uint16 imp_lev, uint8 ctxt, uint8 eff, qos->sec_imp_level = imp_lev; qos->sec_ctxt_mode = ctxt; qos->effective_only = eff; - qos->unknown = unknown; } /******************************************************************* @@ -178,13 +176,10 @@ static BOOL lsa_io_sec_qos(char *desc, LSA_SEC_QOS *qos, prs_struct *ps, return False; if(!prs_uint8 ("effective_only", ps, depth, &qos->effective_only)) return False; - if(!prs_uint32("unknown ", ps, depth, &qos->unknown)) - return False; if (qos->len != prs_offset(ps) - start) { DEBUG(3,("lsa_io_sec_qos: length %x does not match size %x\n", qos->len, prs_offset(ps) - start)); - return False; } return True; @@ -255,7 +250,11 @@ static BOOL lsa_io_obj_attr(char *desc, LSA_OBJ_ATTR *attr, prs_struct *ps, } #endif - if (attr->ptr_sec_qos != 0 && attr->sec_qos != NULL) { + if (attr->ptr_sec_qos != 0) { + if (UNMARSHALLING(ps)) + if (!(attr->sec_qos = (LSA_SEC_QOS *)prs_alloc_mem(ps,sizeof(LSA_SEC_QOS)))) + return False; + if(!lsa_io_sec_qos("sec_qos", attr->sec_qos, ps, depth)) return False; } @@ -277,8 +276,7 @@ void init_q_open_pol(LSA_Q_OPEN_POL *r_q, uint16 system_name, r_q->ptr = 1; /* undocumented pointer */ - if (qos == NULL) - r_q->des_access = desired_access; + r_q->des_access = desired_access; r_q->system_name = system_name; init_lsa_obj_attr(&r_q->attr, attributes, qos); @@ -304,10 +302,8 @@ BOOL lsa_io_q_open_pol(char *desc, LSA_Q_OPEN_POL *r_q, prs_struct *ps, if(!lsa_io_obj_attr("", &r_q->attr, ps, depth)) return False; - if (r_q->attr.ptr_sec_qos == 0) { - if(!prs_uint32("des_access", ps, depth, &r_q->des_access)) - return False; - } + if(!prs_uint32("des_access", ps, depth, &r_q->des_access)) + return False; return True; } @@ -344,8 +340,7 @@ void init_q_open_pol2(LSA_Q_OPEN_POL2 *r_q, char *server_name, r_q->ptr = 1; /* undocumented pointer */ - if (qos == NULL) - r_q->des_access = desired_access; + r_q->des_access = desired_access; init_unistr2(&r_q->uni_server_name, server_name, strlen(server_name) + 1); @@ -371,10 +366,8 @@ BOOL lsa_io_q_open_pol2(char *desc, LSA_Q_OPEN_POL2 *r_q, prs_struct *ps, if(!lsa_io_obj_attr("", &r_q->attr, ps, depth)) return False; - if (r_q->attr.ptr_sec_qos == 0) { - if(!prs_uint32("des_access", ps, depth, &r_q->des_access)) - return False; - } + if(!prs_uint32("des_access", ps, depth, &r_q->des_access)) + return False; return True; } @@ -1608,6 +1601,9 @@ BOOL lsa_io_q_unk_get_connuser(char *desc, LSA_Q_UNK_GET_CONNUSER *q_c, prs_stru if(!smb_io_unistr2("uni2_srvname", &q_c->uni2_srvname, q_c->ptr_srvname, ps, depth)) /* server name to be looked up */ return False; + if (!prs_align(ps)) + return False; + if(!prs_uint32("unk1", ps, depth, &q_c->unk1)) return False; if(!prs_uint32("unk2", ps, depth, &q_c->unk2)) diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index d5ea156eb6..fa95e9f79f 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -36,6 +36,13 @@ struct lsa_info { uint32 access; }; +struct generic_mapping lsa_generic_mapping = { + POLICY_READ, + POLICY_WRITE, + POLICY_EXECUTE, + POLICY_ALL_ACCESS +}; + /******************************************************************* Function to free the per handle data. ********************************************************************/ @@ -290,16 +297,73 @@ static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l, r_l->status = NT_STATUS_OK; } +static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size) +{ + extern DOM_SID global_sid_World; + extern DOM_SID global_sid_Builtin; + DOM_SID local_adm_sid; + DOM_SID adm_sid; + + SEC_ACE ace[3]; + SEC_ACCESS mask; + + SEC_ACL *psa = NULL; + + init_sec_access(&mask, POLICY_EXECUTE); + init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); + + sid_copy(&adm_sid, &global_sam_sid); + sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS); + init_sec_access(&mask, POLICY_ALL_ACCESS); + init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); + + sid_copy(&local_adm_sid, &global_sid_Builtin); + sid_append_rid(&local_adm_sid, BUILTIN_ALIAS_RID_ADMINS); + init_sec_access(&mask, POLICY_ALL_ACCESS); + init_sec_ace(&ace[2], &local_adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); + + if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 3, ace)) == NULL) + return NT_STATUS_NO_MEMORY; + + if((*sd = make_sec_desc(mem_ctx, SEC_DESC_REVISION, &adm_sid, NULL, NULL, psa, sd_size)) == NULL) + return NT_STATUS_NO_MEMORY; + + return NT_STATUS_OK; +} + /*************************************************************************** _lsa_open_policy2. ***************************************************************************/ NTSTATUS _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL2 *r_u) { - /* lkclXXXX having decoded it, ignore all fields in the open policy! */ + struct lsa_info *info; + SEC_DESC *psd = NULL; + size_t sd_size; + uint32 des_access=q_u->des_access; + uint32 acc_granted; + NTSTATUS status; + + + /* map the generic bits to the lsa policy ones */ + se_map_generic(&des_access, &lsa_generic_mapping); + + /* get the generic lsa policy SD until we store it */ + lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size); + + if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) + return status; + + /* associate the domain 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 = global_sam_sid; + info->access = acc_granted; /* set up the LSA QUERY INFO response */ - if (!create_policy_hnd(p, &r_u->pol, NULL, NULL)) + if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info)) return NT_STATUS_OBJECT_NAME_NOT_FOUND; return NT_STATUS_OK; @@ -311,10 +375,33 @@ NTSTATUS _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL NTSTATUS _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL *r_u) { - /* lkclXXXX having decoded it, ignore all fields in the open policy! */ + struct lsa_info *info; + SEC_DESC *psd = NULL; + size_t sd_size; + uint32 des_access=q_u->des_access; + uint32 acc_granted; + NTSTATUS status; + + + /* map the generic bits to the lsa policy ones */ + se_map_generic(&des_access, &lsa_generic_mapping); + + /* get the generic lsa policy SD until we store it */ + lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size); + + if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) + return status; + + /* associate the domain 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 = global_sam_sid; + info->access = acc_granted; /* set up the LSA QUERY INFO response */ - if (!create_policy_hnd(p, &r_u->pol, NULL, NULL)) + if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info)) return NT_STATUS_OBJECT_NAME_NOT_FOUND; return NT_STATUS_OK; @@ -326,13 +413,18 @@ NTSTATUS _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL * NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_ENUM_TRUST_DOM *r_u) { + struct lsa_info *info; uint32 enum_context = 0; char *dom_name = NULL; DOM_SID *dom_sid = NULL; - if (!find_policy_by_hnd(p, &q_u->pol, NULL)) + if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) return NT_STATUS_INVALID_HANDLE; + /* check if the user have enough rights */ + if (!(info->access & POLICY_VIEW_LOCAL_INFORMATION)) + return NT_STATUS_ACCESS_DENIED; + /* set up the LSA QUERY INFO response */ init_r_enum_trust_dom(p->mem_ctx, r_u, enum_context, dom_name, dom_sid, dom_name != NULL ? NT_STATUS_OK : NT_STATUS_NO_MORE_ENTRIES); @@ -346,6 +438,7 @@ NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_E 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; DOM_SID domain_sid; char *name = NULL; @@ -353,24 +446,32 @@ NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INF r_u->status = NT_STATUS_OK; - if (!find_policy_by_hnd(p, &q_u->pol, NULL)) + if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) return NT_STATUS_INVALID_HANDLE; switch (q_u->info_class) { case 0x02: { - unsigned int i; - /* fake info: We audit everything. ;) */ - info->id2.auditing_enabled = 1; - info->id2.count1 = 7; - info->id2.count2 = 7; - if ((info->id2.auditsettings = (uint32 *)talloc(p->mem_ctx,7*sizeof(uint32))) == NULL) - return NT_STATUS_NO_MEMORY; - for (i = 0; i < 7; i++) - info->id2.auditsettings[i] = 3; - break; + unsigned int i; + /* check if the user have enough rights */ + if (!(handle->access & POLICY_VIEW_AUDIT_INFORMATION)) + 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 = (uint32 *)talloc(p->mem_ctx,7*sizeof(uint32))) == NULL) + return NT_STATUS_NO_MEMORY; + for (i = 0; i < 7; i++) + info->id2.auditsettings[i] = 3; + break; } case 0x03: + /* check if the user have enough rights */ + if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + return NT_STATUS_ACCESS_DENIED; + /* Request PolicyPrimaryDomainInformation. */ switch (lp_server_role()) { case ROLE_DOMAIN_PDC: @@ -397,6 +498,10 @@ NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INF init_dom_query(&r_u->dom.id3, name, sid); break; case 0x05: + /* check if the user have enough rights */ + if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + return NT_STATUS_ACCESS_DENIED; + /* Request PolicyAccountDomainInformation. */ switch (lp_server_role()) { case ROLE_DOMAIN_PDC: @@ -418,6 +523,10 @@ NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INF init_dom_query(&r_u->dom.id5, name, sid); break; case 0x06: + /* check if the user have enough rights */ + if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + return NT_STATUS_ACCESS_DENIED; + switch (lp_server_role()) { case ROLE_DOMAIN_BDC: /* @@ -455,15 +564,20 @@ NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INF NTSTATUS _lsa_lookup_sids(pipes_struct *p, LSA_Q_LOOKUP_SIDS *q_u, LSA_R_LOOKUP_SIDS *r_u) { + struct lsa_info *handle; DOM_SID2 *sid = q_u->sids.sid; int num_entries = q_u->sids.num_entries; DOM_R_REF *ref = NULL; LSA_TRANS_NAME_ENUM *names = NULL; uint32 mapped_count = 0; - if (!find_policy_by_hnd(p, &q_u->pol, NULL)) + if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) return NT_STATUS_INVALID_HANDLE; + /* check if the user have enough rights */ + if (!(handle->access & POLICY_LOOKUP_NAMES)) + return NT_STATUS_ACCESS_DENIED; + ref = (DOM_R_REF *)talloc_zero(p->mem_ctx, sizeof(DOM_R_REF)); names = (LSA_TRANS_NAME_ENUM *)talloc_zero(p->mem_ctx, sizeof(LSA_TRANS_NAME_ENUM)); @@ -483,15 +597,20 @@ lsa_reply_lookup_names NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP_NAMES *r_u) { + struct lsa_info *handle; UNISTR2 *names = q_u->uni_name; int num_entries = q_u->num_entries; DOM_R_REF *ref; DOM_RID2 *rids; uint32 mapped_count = 0; - if (!find_policy_by_hnd(p, &q_u->pol, NULL)) + if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) return NT_STATUS_INVALID_HANDLE; + /* check if the user have enough rights */ + if (!(handle->access & POLICY_LOOKUP_NAMES)) + return NT_STATUS_ACCESS_DENIED; + ref = (DOM_R_REF *)talloc_zero(p->mem_ctx, sizeof(DOM_R_REF)); rids = (DOM_RID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_RID2)*MAX_LOOKUP_SIDS); @@ -533,15 +652,24 @@ _lsa_enum_privs. NTSTATUS _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIVS *r_u) { + struct lsa_info *handle; uint32 i; uint32 enum_context=q_u->enum_context; LSA_PRIV_ENTRY *entry; LSA_PRIV_ENTRY *entries=NULL; - if (!find_policy_by_hnd(p, &q_u->pol, NULL)) + if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) return NT_STATUS_INVALID_HANDLE; + /* check if the user have enough rights */ + + /* + * I don't know if it's the right one. not documented. + */ + if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + return NT_STATUS_ACCESS_DENIED; + if (enum_context >= PRIV_ALL_INDEX) return NT_STATUS_NO_MORE_ENTRIES; @@ -579,12 +707,21 @@ _lsa_priv_get_dispname. NTSTATUS _lsa_priv_get_dispname(pipes_struct *p, LSA_Q_PRIV_GET_DISPNAME *q_u, LSA_R_PRIV_GET_DISPNAME *r_u) { + struct lsa_info *handle; fstring name_asc; int i=1; - if (!find_policy_by_hnd(p, &q_u->pol, NULL)) + if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) return NT_STATUS_INVALID_HANDLE; + /* check if the user have enough rights */ + + /* + * I don't know if it's the right one. not documented. + */ + if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + return NT_STATUS_ACCESS_DENIED; + unistr2_to_ascii(name_asc, &q_u->name, sizeof(name_asc)); DEBUG(10,("_lsa_priv_get_dispname: %s", name_asc)); @@ -613,14 +750,23 @@ _lsa_enum_accounts. NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENUM_ACCOUNTS *r_u) { + struct lsa_info *handle; 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)) + if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) return NT_STATUS_INVALID_HANDLE; + /* check if the user have enough rights */ + + /* + * I don't know if it's the right one. not documented. + */ + if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + return NT_STATUS_ACCESS_DENIED; + /* get the list of mapped groups (domain, local, builtin) */ if(!enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV)) return NT_STATUS_OK; @@ -652,32 +798,32 @@ NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENU NTSTATUS _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R_UNK_GET_CONNUSER *r_u) { - fstring username, domname; - int ulen, dlen; - user_struct *vuser = get_valid_user_struct(p->vuid); + fstring username, domname; + int ulen, dlen; + user_struct *vuser = get_valid_user_struct(p->vuid); - if (vuser == NULL) - return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + if (vuser == NULL) + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - fstrcpy(username, vuser->user.smb_name); - fstrcpy(domname, vuser->user.domain); + fstrcpy(username, vuser->user.smb_name); + fstrcpy(domname, vuser->user.domain); - ulen = strlen(username) + 1; - dlen = strlen(domname) + 1; + ulen = strlen(username) + 1; + dlen = strlen(domname) + 1; - init_uni_hdr(&r_u->hdr_user_name, ulen); - r_u->ptr_user_name = 1; - init_unistr2(&r_u->uni2_user_name, username, ulen); + init_uni_hdr(&r_u->hdr_user_name, ulen); + r_u->ptr_user_name = 1; + init_unistr2(&r_u->uni2_user_name, username, ulen); - r_u->unk1 = 1; + r_u->unk1 = 1; - init_uni_hdr(&r_u->hdr_dom_name, dlen); - r_u->ptr_dom_name = 1; - init_unistr2(&r_u->uni2_dom_name, domname, dlen); + init_uni_hdr(&r_u->hdr_dom_name, dlen); + r_u->ptr_dom_name = 1; + init_unistr2(&r_u->uni2_dom_name, domname, dlen); - r_u->status = NT_STATUS_OK; + r_u->status = NT_STATUS_OK; - return r_u->status; + return r_u->status; } /*************************************************************************** @@ -686,14 +832,24 @@ NTSTATUS _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENACCOUNT *r_u) { + struct lsa_info *handle; struct lsa_info *info; r_u->status = NT_STATUS_OK; /* find the connection policy handle. */ - if (!find_policy_by_hnd(p, &q_u->pol, NULL)) + if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) return NT_STATUS_INVALID_HANDLE; + /* check if the user have enough rights */ + + /* + * I don't know if it's the right one. not documented. + * but guessed with rpcclient. + */ + if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION)) + return NT_STATUS_ACCESS_DENIED; + /* 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; @@ -919,54 +1075,39 @@ NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEP NTSTATUS _lsa_query_secobj(pipes_struct *p, LSA_Q_QUERY_SEC_OBJ *q_u, LSA_R_QUERY_SEC_OBJ *r_u) { - struct lsa_info *info=NULL; - extern DOM_SID global_sid_World; - extern DOM_SID global_sid_Builtin; - DOM_SID adm_sid; - - SEC_ACE ace[2]; - SEC_ACCESS mask; - - SEC_ACL *psa = NULL; + struct lsa_info *handle=NULL; SEC_DESC *psd = NULL; size_t sd_size; + NTSTATUS status; r_u->status = NT_STATUS_OK; /* find the connection policy handle. */ - if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) + if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) return NT_STATUS_INVALID_HANDLE; + /* check if the user have enough rights */ + if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + return NT_STATUS_ACCESS_DENIED; + switch (q_u->sec_info) { case 1: /* SD contains only the owner */ - sid_copy(&adm_sid, &global_sid_Builtin); - sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS); - - if((psd = make_sec_desc(p->mem_ctx, SEC_DESC_REVISION, &adm_sid, NULL, NULL, NULL, &sd_size)) == NULL) + status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size); + if(!NT_STATUS_IS_OK(status)) return NT_STATUS_NO_MEMORY; + if((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL) return NT_STATUS_NO_MEMORY; break; case 4: /* SD contains only the ACL */ - init_sec_access(&mask, POLICY_EXECUTE); - init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - - sid_copy(&adm_sid, &global_sid_Builtin); - sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS); - - init_sec_access(&mask, POLICY_ALL_ACCESS); - init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - - if((psa = make_sec_acl(p->mem_ctx, NT4_ACL_REVISION, 2, ace)) == NULL) - return NT_STATUS_NO_MEMORY; - - if((psd = make_sec_desc(p->mem_ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, &sd_size)) == NULL) + status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size); + if(!NT_STATUS_IS_OK(status)) return NT_STATUS_NO_MEMORY; if((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL) |