Added "admin_session" method.
authorNadezhda Ivanova <nadezhda.ivanova@postpath.com>
Thu, 3 Sep 2009 11:39:40 +0000 (14:39 +0300)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 9 Sep 2009 08:57:50 +0000 (18:57 +1000)
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.

source4/auth/pyauth.c
source4/auth/session.h
source4/auth/system_session.c
source4/scripting/python/samba/provision.py

index 04880b71c93961172f16e53aae8ef706d5de01a8..5bb775aa95f962238c46adce6c4440ce7b781a31 100644 (file)
@@ -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 },
 };
 
index 15570c4414f752507b9d24ae97c69869f9ce2261..ca47af33f411d3b338af9858f77fe8de20cd9354 100644 (file)
@@ -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 */
index 07b006064382e9b6345ec920f6775223ba6cf11e..8e22bd820e65f16218082fc0c0cb83e2251f248c 100644 (file)
@@ -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;
+}
index 27b5369ea146666076d04973b654e053e4e8c47c..778271f1d5ce520457425533ffbe627d6496a266 100644 (file)
@@ -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