Added "admin_session" method.
[ira/wip.git] / source4 / auth / system_session.c
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;
+}