From 0eea8ecfe262e515011e7637c5a574f23923f169 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 11 Sep 2010 16:58:45 +1000 Subject: s4-privs Seperate rights and privileges These are related, but slightly different concepts. The biggest difference is that rights are not enumerated as a system-wide list. This moves the rights to security.idl due to dependencies. Andrew Bartlett --- source4/dsdb/samdb/samdb_privilege.c | 8 +++- source4/rpc_server/lsa/dcesrv_lsa.c | 86 ++++++++++++++++++++---------------- 2 files changed, 55 insertions(+), 39 deletions(-) (limited to 'source4') diff --git a/source4/dsdb/samdb/samdb_privilege.c b/source4/dsdb/samdb/samdb_privilege.c index 6186097d78..69c4ebea61 100644 --- a/source4/dsdb/samdb/samdb_privilege.c +++ b/source4/dsdb/samdb/samdb_privilege.c @@ -70,8 +70,12 @@ static NTSTATUS samdb_privilege_setup_sid(struct ldb_context *pdb, TALLOC_CTX *m const char *priv_str = (const char *)el->values[i].data; enum sec_privilege privilege = sec_privilege_id(priv_str); if (privilege == SEC_PRIV_INVALID) { - DEBUG(1,("Unknown privilege '%s' in samdb\n", - priv_str)); + uint32_t right_bit = sec_right_bit(priv_str); + security_token_set_right_bit(token, right_bit); + if (right_bit == 0) { + DEBUG(1,("Unknown privilege '%s' in samdb\n", + priv_str)); + } continue; } security_token_set_privilege(token, privilege); diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index 675aa178a7..81ad6f7a92 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -2410,7 +2410,7 @@ static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call, struct dcesrv_handle *h; struct lsa_account_state *astate; int ret; - unsigned int i; + unsigned int i, j; struct ldb_message **res; const char * const attrs[] = { "privilege", NULL}; struct ldb_message_element *el; @@ -2456,17 +2456,20 @@ static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call, return NT_STATUS_NO_MEMORY; } + j = 0; for (i=0;inum_values;i++) { int id = sec_privilege_id((const char *)el->values[i].data); if (id == SEC_PRIV_INVALID) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; + /* Perhaps an account right, not a privilege */ + continue; } - privs->set[i].attribute = 0; - privs->set[i].luid.low = id; - privs->set[i].luid.high = 0; + privs->set[j].attribute = 0; + privs->set[j].luid.low = id; + privs->set[j].luid.high = 0; + j++; } - privs->count = el->num_values; + privs->count = j; return NT_STATUS_OK; } @@ -2585,6 +2588,11 @@ static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_ for (i=0;icount;i++) { if (sec_privilege_id(rights->names[i].string) == SEC_PRIV_INVALID) { + if (sec_right_bit(rights->names[i].string) == 0) { + talloc_free(msg); + return NT_STATUS_NO_SUCH_PRIVILEGE; + } + talloc_free(msg); return NT_STATUS_NO_SUCH_PRIVILEGE; } @@ -2765,43 +2773,47 @@ static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_cal static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_GetSystemAccessAccount *r) { - uint32_t i; - NTSTATUS status; - struct lsa_EnumPrivsAccount enumPrivs; - struct lsa_PrivilegeSet *privs; + struct dcesrv_handle *h; + struct lsa_account_state *astate; + int ret; + unsigned int i; + struct ldb_message **res; + const char * const attrs[] = { "privilege", NULL}; + struct ldb_message_element *el; + const char *sidstr; - privs = talloc(mem_ctx, struct lsa_PrivilegeSet); - if (!privs) { - return NT_STATUS_NO_MEMORY; - } - privs->count = 0; - privs->unknown = 0; - privs->set = NULL; + *(r->out.access_mask) = 0x00000000; - enumPrivs.in.handle = r->in.handle; - enumPrivs.out.privs = &privs; + DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT); - status = dcesrv_lsa_EnumPrivsAccount(dce_call, mem_ctx, &enumPrivs); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + astate = h->data; - *(r->out.access_mask) = 0x00000000; + sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid); + if (sidstr == NULL) { + return NT_STATUS_NO_MEMORY; + } - for (i = 0; i < privs->count; i++) { - int priv = privs->set[i].luid.low; + ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs, + "objectSid=%s", sidstr); + if (ret < 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + if (ret != 1) { + return NT_STATUS_OK; + } - switch (priv) { - case SEC_PRIV_INTERACTIVE_LOGON: - *(r->out.access_mask) |= LSA_POLICY_MODE_INTERACTIVE; - break; - case SEC_PRIV_NETWORK_LOGON: - *(r->out.access_mask) |= LSA_POLICY_MODE_NETWORK; - break; - case SEC_PRIV_REMOTE_INTERACTIVE_LOGON: - *(r->out.access_mask) |= LSA_POLICY_MODE_REMOTE_INTERACTIVE; - break; + el = ldb_msg_find_element(res[0], "privilege"); + if (el == NULL || el->num_values == 0) { + return NT_STATUS_OK; + } + + for (i=0;inum_values;i++) { + uint32_t right_bit = sec_right_bit((const char *)el->values[i].data); + if (right_bit == 0) { + /* Perhaps an privilege, not a right */ + continue; } + *(r->out.access_mask) |= right_bit; } return NT_STATUS_OK; @@ -3495,7 +3507,7 @@ static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *d } privname = r->in.name->string; - if (sec_privilege_id(privname) == SEC_PRIV_INVALID) { + if (sec_privilege_id(privname) == SEC_PRIV_INVALID && sec_right_bit(privname) == 0) { return NT_STATUS_NO_SUCH_PRIVILEGE; } -- cgit