diff options
author | Nadezhda Ivanova <nadezhda.ivanova@postpath.com> | 2009-09-03 14:39:40 +0300 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2009-09-09 18:57:50 +1000 |
commit | 269fe99a62371fb9540d886f7cc619450c5b5c8d (patch) | |
tree | cca34fdf18826ed84e13088f1448fde1ec3f1307 /source4 | |
parent | 8640293fabb0fd0fe92b814411577dcdb449100d (diff) | |
download | samba-269fe99a62371fb9540d886f7cc619450c5b5c8d.tar.gz samba-269fe99a62371fb9540d886f7cc619450c5b5c8d.tar.xz samba-269fe99a62371fb9540d886f7cc619450c5b5c8d.zip |
Added "admin_session" method.
The purpose of admin_session is to be able to execute parts of provisioning
as the user Administrator in order to have the correct group and owner in the
security descriptors. To be used for provisioning and tests only.
Diffstat (limited to 'source4')
-rw-r--r-- | source4/auth/pyauth.c | 23 | ||||
-rw-r--r-- | source4/auth/session.h | 4 | ||||
-rw-r--r-- | source4/auth/system_session.c | 191 | ||||
-rw-r--r-- | source4/scripting/python/samba/provision.py | 6 |
4 files changed, 223 insertions, 1 deletions
diff --git a/source4/auth/pyauth.c b/source4/auth/pyauth.c index 04880b71c9..5bb775aa95 100644 --- a/source4/auth/pyauth.c +++ b/source4/auth/pyauth.c @@ -21,6 +21,8 @@ #include "pyauth.h" #include "auth/system_session_proto.h" #include "param/pyparam.h" +#include "libcli/security/security.h" + PyTypeObject PyAuthSession = { .tp_name = "AuthSession", @@ -70,9 +72,30 @@ static PyObject *py_system_session_anon(PyObject *module, PyObject *args) return PyAuthSession_FromSession(session); } +static PyObject *py_admin_session(PyObject *module, PyObject *args) +{ + PyObject *py_lp_ctx; + PyObject *py_sid; + struct loadparm_context *lp_ctx = NULL; + struct auth_session_info *session; + struct dom_sid *domain_sid = NULL; + if (!PyArg_ParseTuple(args, "OO", &py_lp_ctx, &py_sid)) + return NULL; + + lp_ctx = lp_from_py_object(py_lp_ctx); + if (lp_ctx == NULL) + return NULL; + + domain_sid = dom_sid_parse_talloc(NULL, PyString_AsString(py_sid)); + session = admin_session(NULL, lp_ctx, domain_sid); + + return PyAuthSession_FromSession(session); +} + static PyMethodDef py_auth_methods[] = { { "system_session", (PyCFunction)py_system_session, METH_VARARGS, NULL }, { "system_session_anonymous", (PyCFunction)py_system_session_anon, METH_VARARGS, NULL }, + { "admin_session", (PyCFunction)py_admin_session, METH_VARARGS, NULL }, { NULL }, }; diff --git a/source4/auth/session.h b/source4/auth/session.h index 15570c4414..ca47af33f4 100644 --- a/source4/auth/session.h +++ b/source4/auth/session.h @@ -62,5 +62,9 @@ struct auth_session_info *anonymous_session(TALLOC_CTX *mem_ctx, struct tevent_context *event_ctx, struct loadparm_context *lp_ctx); +struct auth_session_info *admin_session(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, + struct dom_sid *domain_sid); + #endif /* _SAMBA_AUTH_SESSION_H */ diff --git a/source4/auth/system_session.c b/source4/auth/system_session.c index 07b0060643..8e22bd820e 100644 --- a/source4/auth/system_session.c +++ b/source4/auth/system_session.c @@ -303,3 +303,194 @@ NTSTATUS auth_system_server_info(TALLOC_CTX *mem_ctx, const char *netbios_name, } +/* Create server info for the Administrator account. This should only be used + * during provisioning when we need to impersonate Administrator but + * the account has not been created yet */ + +static NTSTATUS create_admin_token(TALLOC_CTX *mem_ctx, + struct dom_sid *user_sid, + struct dom_sid *group_sid, + int n_groupSIDs, + struct dom_sid **groupSIDs, + struct security_token **token) +{ + struct security_token *ptoken; + int i; + + ptoken = security_token_initialise(mem_ctx); + NT_STATUS_HAVE_NO_MEMORY(ptoken); + + ptoken->sids = talloc_array(ptoken, struct dom_sid *, n_groupSIDs + 3); + NT_STATUS_HAVE_NO_MEMORY(ptoken->sids); + + ptoken->user_sid = talloc_reference(ptoken, user_sid); + ptoken->group_sid = talloc_reference(ptoken, group_sid); + ptoken->privilege_mask = 0; + + ptoken->sids[0] = ptoken->user_sid; + ptoken->sids[1] = ptoken->group_sid; + ptoken->sids[2] = dom_sid_parse_talloc(ptoken->sids, SID_NT_AUTHENTICATED_USERS); + NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[2]); + ptoken->num_sids = 3; + + + for (i = 0; i < n_groupSIDs; i++) { + size_t check_sid_idx; + for (check_sid_idx = 1; + check_sid_idx < ptoken->num_sids; + check_sid_idx++) { + if (dom_sid_equal(ptoken->sids[check_sid_idx], groupSIDs[i])) { + break; + } + } + + if (check_sid_idx == ptoken->num_sids) { + ptoken->sids[ptoken->num_sids++] = talloc_reference(ptoken->sids, groupSIDs[i]); + } + } + + *token = ptoken; + ptoken->privilege_mask = ~0; + return NT_STATUS_OK; +} + +static NTSTATUS auth_domain_admin_server_info(TALLOC_CTX *mem_ctx, + const char *netbios_name, + const char *domain_name, + struct dom_sid *domain_sid, + struct auth_serversupplied_info **_server_info) +{ + struct auth_serversupplied_info *server_info; + + server_info = talloc(mem_ctx, struct auth_serversupplied_info); + NT_STATUS_HAVE_NO_MEMORY(server_info); + + server_info->account_sid = dom_sid_add_rid(server_info, domain_sid, DOMAIN_RID_ADMINISTRATOR); + NT_STATUS_HAVE_NO_MEMORY(server_info->account_sid); + + server_info->primary_group_sid = dom_sid_add_rid(server_info, domain_sid, DOMAIN_RID_USERS); + NT_STATUS_HAVE_NO_MEMORY(server_info->primary_group_sid); + + server_info->n_domain_groups = 6; + server_info->domain_groups = talloc_array(server_info, struct dom_sid *, server_info->n_domain_groups); + + server_info->domain_groups[0] = dom_sid_parse_talloc(server_info, SID_BUILTIN_ADMINISTRATORS); + server_info->domain_groups[1] = dom_sid_add_rid(server_info, domain_sid, DOMAIN_RID_ADMINS); + server_info->domain_groups[2] = dom_sid_add_rid(server_info, domain_sid, DOMAIN_RID_USERS); + server_info->domain_groups[3] = dom_sid_add_rid(server_info, domain_sid, DOMAIN_RID_ENTERPRISE_ADMINS); + server_info->domain_groups[4] = dom_sid_add_rid(server_info, domain_sid, DOMAIN_RID_POLICY_ADMINS); + server_info->domain_groups[5] = dom_sid_add_rid(server_info, domain_sid, DOMAIN_RID_SCHEMA_ADMINS); + + /* What should the session key be?*/ + server_info->user_session_key = data_blob_talloc(server_info, NULL, 16); + NT_STATUS_HAVE_NO_MEMORY(server_info->user_session_key.data); + + server_info->lm_session_key = data_blob_talloc(server_info, NULL, 16); + NT_STATUS_HAVE_NO_MEMORY(server_info->lm_session_key.data); + + data_blob_clear(&server_info->user_session_key); + data_blob_clear(&server_info->lm_session_key); + + server_info->account_name = talloc_strdup(server_info, "Administrator"); + NT_STATUS_HAVE_NO_MEMORY(server_info->account_name); + + server_info->domain_name = talloc_strdup(server_info, domain_name); + NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name); + + server_info->full_name = talloc_strdup(server_info, "Administrator"); + NT_STATUS_HAVE_NO_MEMORY(server_info->full_name); + + server_info->logon_script = talloc_strdup(server_info, ""); + NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script); + + server_info->profile_path = talloc_strdup(server_info, ""); + NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path); + + server_info->home_directory = talloc_strdup(server_info, ""); + NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory); + + server_info->home_drive = talloc_strdup(server_info, ""); + NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive); + + server_info->logon_server = talloc_strdup(server_info, netbios_name); + NT_STATUS_HAVE_NO_MEMORY(server_info->logon_server); + + server_info->last_logon = 0; + server_info->last_logoff = 0; + server_info->acct_expiry = 0; + server_info->last_password_change = 0; + server_info->allow_password_change = 0; + server_info->force_password_change = 0; + + server_info->logon_count = 0; + server_info->bad_password_count = 0; + + server_info->acct_flags = ACB_NORMAL; + + server_info->authenticated = true; + + *_server_info = server_info; + + return NT_STATUS_OK; +} + +static NTSTATUS auth_domain_admin_session_info(TALLOC_CTX *parent_ctx, + struct loadparm_context *lp_ctx, + struct dom_sid *domain_sid, + struct auth_session_info **_session_info) +{ + NTSTATUS nt_status; + struct auth_serversupplied_info *server_info = NULL; + struct auth_session_info *session_info = NULL; + TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); + + nt_status = auth_domain_admin_server_info(mem_ctx, lp_netbios_name(lp_ctx), + lp_workgroup(lp_ctx), domain_sid, + &server_info); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(mem_ctx); + return nt_status; + } + + session_info = talloc(mem_ctx, struct auth_session_info); + NT_STATUS_HAVE_NO_MEMORY(session_info); + + session_info->server_info = talloc_reference(session_info, server_info); + + /* unless set otherwise, the session key is the user session + * key from the auth subsystem */ + session_info->session_key = server_info->user_session_key; + + nt_status = create_admin_token(session_info, + server_info->account_sid, + server_info->primary_group_sid, + server_info->n_domain_groups, + server_info->domain_groups, + &session_info->security_token); + NT_STATUS_NOT_OK_RETURN(nt_status); + + session_info->credentials = cli_credentials_init(session_info); + if (!session_info->credentials) { + return NT_STATUS_NO_MEMORY; + } + + cli_credentials_set_conf(session_info->credentials, lp_ctx); + + *_session_info = session_info; + + return NT_STATUS_OK; +} + +_PUBLIC_ struct auth_session_info *admin_session(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct dom_sid *domain_sid) +{ + NTSTATUS nt_status; + struct auth_session_info *session_info = NULL; + nt_status = auth_domain_admin_session_info(mem_ctx, + lp_ctx, + domain_sid, + &session_info); + if (!NT_STATUS_IS_OK(nt_status)) { + return NULL; + } + return session_info; +} diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 27b5369ea1..778271f1d5 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -40,7 +40,7 @@ import subprocess import shutil from credentials import Credentials, DONT_USE_KERBEROS -from auth import system_session +from auth import system_session, admin_session from samba import version, Ldb, substitute_var, valid_netbios_name, check_all_substituted, \ DS_BEHAVIOR_WIN2008 from samba.samdb import SamDB @@ -863,6 +863,10 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, else: domain_oc = "samba4LocalDomain" +#impersonate domain admin + admin_session_info = admin_session(lp, str(domainsid)) + samdb.set_session_info(admin_session_info) + setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), { "DOMAINDN": names.domaindn, "DOMAIN_OC": domain_oc |