summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2010-09-11 16:58:45 +1000
committerAndrew Bartlett <abartlet@samba.org>2010-09-11 18:46:13 +1000
commit0eea8ecfe262e515011e7637c5a574f23923f169 (patch)
tree1138c3247f29585df7af3579bb2cb1d018783ac6
parent3b4db34011f06fb785153fa9070fb1da9d8f5c78 (diff)
downloadsamba-0eea8ecfe262e515011e7637c5a574f23923f169.tar.gz
samba-0eea8ecfe262e515011e7637c5a574f23923f169.tar.bz2
samba-0eea8ecfe262e515011e7637c5a574f23923f169.zip
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
-rw-r--r--libcli/security/privileges.c65
-rw-r--r--libcli/security/privileges.h9
-rw-r--r--librpc/idl/lsa.idl16
-rw-r--r--librpc/idl/security.idl35
-rw-r--r--source4/dsdb/samdb/samdb_privilege.c8
-rw-r--r--source4/rpc_server/lsa/dcesrv_lsa.c86
6 files changed, 137 insertions, 82 deletions
diff --git a/libcli/security/privileges.c b/libcli/security/privileges.c
index 466bea0565..1fecf4011d 100644
--- a/libcli/security/privileges.c
+++ b/libcli/security/privileges.c
@@ -59,14 +59,9 @@ static const struct {
{SEC_PRIV_ADD_USERS, SEC_PRIV_ADD_USERS_BIT, "SeAddUsersPrivilege", "Add users and groups to the domain"},
{SEC_PRIV_DISK_OPERATOR, SEC_PRIV_DISK_OPERATOR_BIT, "SeDiskOperatorPrivilege", "Manage disk shares"},
- /* The list from here on was not displayed in the code from
- * source3/ with the comment that usrmgr will display these
- * next 2 twice if you include them. The source4/ code has
- * always included them, but they do not appear in Windows
- * 2008 R2.
-
- Finally, the parameter 'short_list' determines if the short
- or full list (including many other privileges) is used */
+ /* The list from here on is not displayed in the code from
+ * source3, and is after index NUM_SHORT_LIST_PRIVS for that
+ * reason */
{SEC_PRIV_SECURITY,
SEC_PRIV_SECURITY_BIT,
@@ -152,19 +147,26 @@ static const struct {
SEC_PRIV_ENABLE_DELEGATION_BIT,
"SeEnableDelegationPrivilege",
"Enable Delegation"},
+};
- {SEC_PRIV_INTERACTIVE_LOGON,
- SEC_PRIV_INTERACTIVE_LOGON_BIT,
+/* These are rights, not privileges, and should not be confused. The
+ * names are very similar, and they are quite similar in behaviour,
+ * but they are not to be enumerated as a system-wide list or have an
+ * LUID value */
+static const struct {
+ uint32_t right_mask;
+ const char *name;
+ const char *description;
+} rights[] = {
+ {LSA_POLICY_MODE_INTERACTIVE,
"SeInteractiveLogonRight",
"Interactive logon"},
- {SEC_PRIV_NETWORK_LOGON,
- SEC_PRIV_NETWORK_LOGON_BIT,
+ {LSA_POLICY_MODE_NETWORK,
"SeNetworkLogonRight",
"Network logon"},
- {SEC_PRIV_REMOTE_INTERACTIVE_LOGON,
- SEC_PRIV_REMOTE_INTERACTIVE_LOGON_BIT,
+ {LSA_POLICY_MODE_REMOTE_INTERACTIVE,
"SeRemoteInteractiveLogonRight",
"Remote Interactive logon"}
};
@@ -369,6 +371,20 @@ enum sec_privilege sec_privilege_id(const char *name)
}
/*
+ map a 'right' name to it's bitmap value. Return 0 if not found
+*/
+uint32_t sec_right_bit(const char *name)
+{
+ int i;
+ for (i=0;i<ARRAY_SIZE(rights);i++) {
+ if (strcasecmp(rights[i].name, name) == 0) {
+ return rights[i].right_mask;
+ }
+ }
+ return 0;
+}
+
+/*
assist in walking the table of privileges - return the LUID (low 32 bits) by index
*/
enum sec_privilege sec_privilege_from_index(int idx)
@@ -419,6 +435,14 @@ void security_token_set_privilege(struct security_token *token, enum sec_privile
token->privilege_mask |= sec_privilege_mask(privilege);
}
+/*
+ set a bit in the rights mask
+*/
+void security_token_set_right_bit(struct security_token *token, uint32_t right_bit)
+{
+ token->rights_mask |= right_bit;
+}
+
void security_token_debug_privileges(int dbg_lev, const struct security_token *token)
{
DEBUGADD(dbg_lev, (" Privileges (0x%16llX):\n",
@@ -434,4 +458,17 @@ void security_token_debug_privileges(int dbg_lev, const struct security_token *t
}
}
}
+ DEBUGADD(dbg_lev, (" Rights (0x%16lX):\n",
+ (unsigned long) token->rights_mask));
+
+ if (token->rights_mask) {
+ int idx = 0;
+ int i = 0;
+ for (idx = 0; idx<ARRAY_SIZE(rights); idx++) {
+ if (token->rights_mask & rights[idx].right_mask) {
+ DEBUGADD(dbg_lev, (" Right[%3lu]: %s\n", (unsigned long)i++,
+ rights[idx].name));
+ }
+ }
+ }
}
diff --git a/libcli/security/privileges.h b/libcli/security/privileges.h
index 25895fd1ff..f67a38bc27 100644
--- a/libcli/security/privileges.h
+++ b/libcli/security/privileges.h
@@ -70,6 +70,11 @@ const char *sec_privilege_display_name(enum sec_privilege privilege, uint16_t *l
enum sec_privilege sec_privilege_id(const char *name);
/*
+ map a 'right' name to it's bitmap value. Return 0 if not found
+*/
+uint32_t sec_right_bit(const char *name);
+
+/*
assist in walking the table of privileges - return the LUID (low 32 bits) by index
*/
enum sec_privilege sec_privilege_from_index(int idx);
@@ -88,6 +93,10 @@ bool security_token_has_privilege(const struct security_token *token, enum sec_p
set a bit in the privilege mask
*/
void security_token_set_privilege(struct security_token *token, enum sec_privilege privilege);
+/*
+ set a bit in the rights mask
+*/
+void security_token_set_right_bit(struct security_token *token, uint32_t right_bit);
void security_token_debug_privileges(int dbg_lev, const struct security_token *token);
diff --git a/librpc/idl/lsa.idl b/librpc/idl/lsa.idl
index e9c65045d9..343d21da07 100644
--- a/librpc/idl/lsa.idl
+++ b/librpc/idl/lsa.idl
@@ -639,22 +639,6 @@ import "misc.idl", "security.idl";
/* Function: 0x16 */
[todo] NTSTATUS lsa_SetQuotasForAccount();
- typedef [bitmap32bit] bitmap {
- LSA_POLICY_MODE_INTERACTIVE = 0x00000001,
- LSA_POLICY_MODE_NETWORK = 0x00000002,
- LSA_POLICY_MODE_BATCH = 0x00000004,
- LSA_POLICY_MODE_SERVICE = 0x00000010,
- LSA_POLICY_MODE_PROXY = 0x00000020,
- LSA_POLICY_MODE_DENY_INTERACTIVE = 0x00000040,
- LSA_POLICY_MODE_DENY_NETWORK = 0x00000080,
- LSA_POLICY_MODE_DENY_BATCH = 0x00000100,
- LSA_POLICY_MODE_DENY_SERVICE = 0x00000200,
- LSA_POLICY_MODE_REMOTE_INTERACTIVE = 0x00000400,
- LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE = 0x00000800,
- LSA_POLICY_MODE_ALL = 0x00000FF7,
- LSA_POLICY_MODE_ALL_NT4 = 0x00000037
- } lsa_SystemAccessModeFlags;
-
/* Function: 0x17 */
NTSTATUS lsa_GetSystemAccessAccount(
[in] policy_handle *handle,
diff --git a/librpc/idl/security.idl b/librpc/idl/security.idl
index 4f5245b2e4..13ccb49537 100644
--- a/librpc/idl/security.idl
+++ b/librpc/idl/security.idl
@@ -32,6 +32,8 @@ cpp_quote("#define dom_sid0 dom_sid")
interface security
{
+ typedef bitmap lsa_SystemAccessModeFlags lsa_SystemAccessModeFlags;
+
typedef [public,gensize,noprint,nosize,nopull,nopush] struct {
uint8 sid_rev_num; /**< SID revision number */
[range(0,15)] int8 num_auths; /**< Number of sub-authorities */
@@ -390,11 +392,7 @@ interface security
/* Samba-specific privs */
SEC_PRIV_PRINT_OPERATOR = 0x1001,
SEC_PRIV_ADD_USERS = 0x1002,
- SEC_PRIV_DISK_OPERATOR = 0x1003,
- /* Windows privs not in the list above */
- SEC_PRIV_INTERACTIVE_LOGON = 0x2022,
- SEC_PRIV_NETWORK_LOGON = 0x2023,
- SEC_PRIV_REMOTE_INTERACTIVE_LOGON = 0x2024
+ SEC_PRIV_DISK_OPERATOR = 0x1003
} sec_privilege;
@@ -403,10 +401,6 @@ interface security
* as a bitmap (privilages.ldb uses the string forms).
*/
typedef [bitmap64bit] bitmap {
- SEC_PRIV_NETWORK_LOGON_BIT = 0x00000001,
- SEC_PRIV_INTERACTIVE_LOGON_BIT = 0x00000002,
- SEC_PRIV_BATCH_LOGON_BIT = 0x00000004,
- SEC_PRIV_SERVICE_LOGON_BIT = 0x00000008,
SEC_PRIV_MACHINE_ACCOUNT_BIT = 0x00000010,
/* Samba-specific privs */
@@ -436,11 +430,25 @@ interface security
SEC_PRIV_ENABLE_DELEGATION_BIT = 0x02000000,
SEC_PRIV_MANAGE_VOLUME_BIT = 0x04000000,
SEC_PRIV_IMPERSONATE_BIT = 0x08000000,
- SEC_PRIV_CREATE_GLOBAL_BIT = 0x10000000,
- /* Windows privs not in the list above */
- SEC_PRIV_REMOTE_INTERACTIVE_LOGON_BIT = 0x20000000
+ SEC_PRIV_CREATE_GLOBAL_BIT = 0x10000000
} se_privilege;
+ typedef [bitmap32bit] bitmap {
+ LSA_POLICY_MODE_INTERACTIVE = 0x00000001,
+ LSA_POLICY_MODE_NETWORK = 0x00000002,
+ LSA_POLICY_MODE_BATCH = 0x00000004,
+ LSA_POLICY_MODE_SERVICE = 0x00000010,
+ LSA_POLICY_MODE_PROXY = 0x00000020,
+ LSA_POLICY_MODE_DENY_INTERACTIVE = 0x00000040,
+ LSA_POLICY_MODE_DENY_NETWORK = 0x00000080,
+ LSA_POLICY_MODE_DENY_BATCH = 0x00000100,
+ LSA_POLICY_MODE_DENY_SERVICE = 0x00000200,
+ LSA_POLICY_MODE_REMOTE_INTERACTIVE = 0x00000400,
+ LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE = 0x00000800,
+ LSA_POLICY_MODE_ALL = 0x00000FF7,
+ LSA_POLICY_MODE_ALL_NT4 = 0x00000037
+ } lsa_SystemAccessModeFlags;
+
typedef [public,bitmap8bit] bitmap {
SEC_ACE_FLAG_OBJECT_INHERIT = 0x01,
SEC_ACE_FLAG_CONTAINER_INHERIT = 0x02,
@@ -564,7 +572,8 @@ interface security
typedef [public] struct {
uint32 num_sids;
[size_is(num_sids)] dom_sid sids[*];
- udlong privilege_mask;
+ se_privilege privilege_mask;
+ lsa_SystemAccessModeFlags rights_mask;
} security_token;
/* bits that determine which parts of a security descriptor
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;i<el->num_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;i<rights->count;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;i<el->num_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;
}