summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/rpc_lsa.h1
-rw-r--r--source3/libsmb/cli_lsarpc.c4
-rw-r--r--source3/rpc_parse/parse_lsa.c34
-rw-r--r--source3/rpc_server/srv_lsa_nt.c275
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)