diff options
-rw-r--r-- | source4/auth/auth_util.c | 8 | ||||
-rw-r--r-- | source4/dsdb/config.mk | 1 | ||||
-rw-r--r-- | source4/dsdb/samdb/samdb_privilege.c | 107 | ||||
-rw-r--r-- | source4/libcli/auth/gensec_krb5.c | 7 | ||||
-rw-r--r-- | source4/libcli/security/privilege.c | 18 |
5 files changed, 136 insertions, 5 deletions
diff --git a/source4/auth/auth_util.c b/source4/auth/auth_util.c index 4a60c3f847..2b6d5324ee 100644 --- a/source4/auth/auth_util.c +++ b/source4/auth/auth_util.c @@ -353,6 +353,7 @@ NTSTATUS create_security_token(TALLOC_CTX *mem_ctx, { struct security_token *ptoken; int i; + NTSTATUS status; ptoken = security_token_initialise(mem_ctx); if (ptoken == NULL) { @@ -397,6 +398,13 @@ NTSTATUS create_security_token(TALLOC_CTX *mem_ctx, ptoken->sids[ptoken->num_sids++] = groupSIDs[i]; } } + + /* setup the privilege mask for this token */ + status = samdb_privilege_setup(ptoken); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(ptoken); + return status; + } debug_security_token(DBGC_AUTH, 10, ptoken); diff --git a/source4/dsdb/config.mk b/source4/dsdb/config.mk index 0cb0698518..333d66a777 100644 --- a/source4/dsdb/config.mk +++ b/source4/dsdb/config.mk @@ -6,6 +6,7 @@ INIT_OBJ_FILES = \ dsdb/samdb/samdb.o ADD_OBJ_FILES = \ + dsdb/samdb/samdb_privilege.o \ dsdb/common/flag_mapping.o REQUIRED_SUBSYSTEMS = \ DCERPC_COMMON \ diff --git a/source4/dsdb/samdb/samdb_privilege.c b/source4/dsdb/samdb/samdb_privilege.c new file mode 100644 index 0000000000..9fb20a84dc --- /dev/null +++ b/source4/dsdb/samdb/samdb_privilege.c @@ -0,0 +1,107 @@ +/* + Unix SMB/CIFS implementation. + + manipulate privilege records in samdb + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "librpc/gen_ndr/ndr_security.h" +#include "lib/ldb/include/ldb.h" + +/* + add privilege bits for one sid to a security_token +*/ +static NTSTATUS samdb_privilege_setup_sid(void *samctx, TALLOC_CTX *mem_ctx, + const struct dom_sid *sid, + uint64_t *mask) +{ + char *sidstr; + const char * const attrs[] = { "privilege", NULL }; + struct ldb_message **res = NULL; + struct ldb_message_element *el; + int ret, i; + + *mask = 0; + + sidstr = dom_sid_string(mem_ctx, sid); + if (sidstr == NULL) { + return NT_STATUS_NO_MEMORY; + } + + ret = samdb_search(samctx, mem_ctx, NULL, &res, attrs, "objectSid=%s", sidstr); + if (ret != 1) { + talloc_free(sidstr); + /* not an error to not match */ + return NT_STATUS_OK; + } + + el = ldb_msg_find_element(res[0], "privilege"); + if (el == NULL) { + talloc_free(sidstr); + return NT_STATUS_OK; + } + + for (i=0;i<el->num_values;i++) { + const char *priv_str = el->values[i].data; + int privilege = sec_privilege_id(priv_str); + if (privilege == -1) { + DEBUG(1,("Unknown privilege '%s' in samdb\n", + priv_str)); + continue; + } + *mask |= sec_privilege_mask(privilege); + } + + return NT_STATUS_OK; +} + +/* + setup the privilege mask for this security token based on our + local SAM +*/ +NTSTATUS samdb_privilege_setup(struct security_token *token) +{ + void *samctx; + TALLOC_CTX *mem_ctx = talloc(token, 0); + int i; + NTSTATUS status; + + samctx = samdb_connect(mem_ctx); + if (samctx == NULL) { + talloc_free(mem_ctx); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + token->privilege_mask = 0; + + for (i=0;i<token->num_sids;i++) { + uint64_t mask; + status = samdb_privilege_setup_sid(samctx, mem_ctx, + token->sids[i], &mask); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return status; + } + token->privilege_mask |= mask; + } + + talloc_free(mem_ctx); + + return NT_STATUS_OK; +} diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c index 602e42a5ff..88e7cdd2e3 100644 --- a/source4/libcli/auth/gensec_krb5.c +++ b/source4/libcli/auth/gensec_krb5.c @@ -716,6 +716,13 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security = dom_sid_add_rid(session_info, sid, logon_info->groups[ptoken->num_sids - 2].rid); } + + /* setup any privileges for this token */ + nt_status = samdb_privilege_setup(ptoken); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(ptoken); + return nt_status; + } debug_security_token(DBGC_AUTH, 0, ptoken); diff --git a/source4/libcli/security/privilege.c b/source4/libcli/security/privilege.c index 10a51c8b42..93599598db 100644 --- a/source4/libcli/security/privilege.c +++ b/source4/libcli/security/privilege.c @@ -85,12 +85,22 @@ int sec_privilege_id(const char *name) /* - return True if a security_token has a particular privilege bit set + return a privilege mask given a privilege id */ -BOOL sec_privilege_check(const struct security_token *token, unsigned int privilege) +uint64_t sec_privilege_mask(unsigned int privilege) { uint64_t mask = 1; mask <<= (privilege-1); + return mask; +} + + +/* + return True if a security_token has a particular privilege bit set +*/ +BOOL sec_privilege_check(const struct security_token *token, unsigned int privilege) +{ + uint64_t mask = sec_privilege_mask(privilege); if (token->privilege_mask & mask) { return True; } @@ -102,7 +112,5 @@ BOOL sec_privilege_check(const struct security_token *token, unsigned int privil */ void sec_privilege_set(struct security_token *token, unsigned int privilege) { - uint64_t mask = 1; - mask <<= (privilege-1); - token->privilege_mask |= mask; + token->privilege_mask |= sec_privilege_mask(privilege); } |