s3-rpcclient: Fix a compile warning.
[samba.git] / source3 / rpc_client / init_netlogon.c
index 62f1fac62623f47014fd8a759b261f6322814941..b2ad1a5bcb53f759c0142c50f220f03a2d902d7c 100644 (file)
@@ -136,6 +136,191 @@ void init_netr_SamInfo3(struct netr_SamInfo3 *r,
        r->sids = sids;
 }
 
+/*******************************************************************
+ gets a domain user's groups from their already-calculated NT_USER_TOKEN
+ ********************************************************************/
+
+static NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx,
+                                      const DOM_SID *domain_sid,
+                                      size_t num_sids,
+                                      const DOM_SID *sids,
+                                      int *numgroups, DOM_GID **pgids)
+{
+       int i;
+
+       *numgroups=0;
+       *pgids = NULL;
+
+       for (i=0; i<num_sids; i++) {
+               DOM_GID gid;
+               if (!sid_peek_check_rid(domain_sid, &sids[i], &gid.g_rid)) {
+                       continue;
+               }
+               gid.attr = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
+                           SE_GROUP_ENABLED);
+               ADD_TO_ARRAY(mem_ctx, DOM_GID, gid, pgids, numgroups);
+               if (*pgids == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+       }
+       return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ inits a netr_SamInfo3 structure from an auth_serversupplied_info. sam3 must
+ already be initialized and is used as the talloc parent for its members.
+*****************************************************************************/
+
+NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info,
+                               uint8_t *pipe_session_key,
+                               size_t pipe_session_key_len,
+                               struct netr_SamInfo3 *sam3)
+{
+       struct samu *sampw;
+       DOM_GID *gids = NULL;
+       const DOM_SID *user_sid = NULL;
+       const DOM_SID *group_sid = NULL;
+       DOM_SID domain_sid;
+       uint32 user_rid, group_rid;
+       NTSTATUS status;
+
+       int num_gids = 0;
+       const char *my_name;
+
+       struct netr_UserSessionKey user_session_key;
+       struct netr_LMSessionKey lm_session_key;
+
+       NTTIME last_logon, last_logoff, acct_expiry, last_password_change;
+       NTTIME allow_password_change, force_password_change;
+       struct samr_RidWithAttributeArray groups;
+       int i;
+       struct dom_sid2 *sid = NULL;
+
+       ZERO_STRUCT(user_session_key);
+       ZERO_STRUCT(lm_session_key);
+
+       sampw = server_info->sam_account;
+
+       user_sid = pdb_get_user_sid(sampw);
+       group_sid = pdb_get_group_sid(sampw);
+
+       if (pipe_session_key && pipe_session_key_len != 16) {
+               DEBUG(0,("serverinfo_to_SamInfo3: invalid "
+                        "pipe_session_key_len[%d] != 16\n",
+                        pipe_session_key_len));
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+
+       if ((user_sid == NULL) || (group_sid == NULL)) {
+               DEBUG(1, ("_netr_LogonSamLogon: User without group or user SID\n"));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       sid_copy(&domain_sid, user_sid);
+       sid_split_rid(&domain_sid, &user_rid);
+
+       sid = sid_dup_talloc(sam3, &domain_sid);
+       if (!sid) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (!sid_peek_check_rid(&domain_sid, group_sid, &group_rid)) {
+               DEBUG(1, ("_netr_LogonSamLogon: user %s\\%s has user sid "
+                         "%s\n but group sid %s.\n"
+                         "The conflicting domain portions are not "
+                         "supported for NETLOGON calls\n",
+                         pdb_get_domain(sampw),
+                         pdb_get_username(sampw),
+                         sid_string_dbg(user_sid),
+                         sid_string_dbg(group_sid)));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       if(server_info->login_server) {
+               my_name = server_info->login_server;
+       } else {
+               my_name = global_myname();
+       }
+
+       status = nt_token_to_group_list(sam3, &domain_sid,
+                                       server_info->num_sids,
+                                       server_info->sids,
+                                       &num_gids, &gids);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       if (server_info->user_session_key.length) {
+               memcpy(user_session_key.key,
+                      server_info->user_session_key.data,
+                      MIN(sizeof(user_session_key.key),
+                          server_info->user_session_key.length));
+               if (pipe_session_key) {
+                       SamOEMhash(user_session_key.key, pipe_session_key, 16);
+               }
+       }
+       if (server_info->lm_session_key.length) {
+               memcpy(lm_session_key.key,
+                      server_info->lm_session_key.data,
+                      MIN(sizeof(lm_session_key.key),
+                          server_info->lm_session_key.length));
+               if (pipe_session_key) {
+                       SamOEMhash(lm_session_key.key, pipe_session_key, 8);
+               }
+       }
+
+       groups.count = num_gids;
+       groups.rids = TALLOC_ARRAY(sam3, struct samr_RidWithAttribute, groups.count);
+       if (!groups.rids) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       for (i=0; i < groups.count; i++) {
+               groups.rids[i].rid = gids[i].g_rid;
+               groups.rids[i].attributes = gids[i].attr;
+       }
+
+       unix_to_nt_time(&last_logon, pdb_get_logon_time(sampw));
+       unix_to_nt_time(&last_logoff, get_time_t_max());
+       unix_to_nt_time(&acct_expiry, get_time_t_max());
+       unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(sampw));
+       unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(sampw));
+       unix_to_nt_time(&force_password_change, pdb_get_pass_must_change_time(sampw));
+
+       init_netr_SamInfo3(sam3,
+                          last_logon,
+                          last_logoff,
+                          acct_expiry,
+                          last_password_change,
+                          allow_password_change,
+                          force_password_change,
+                          talloc_strdup(sam3, pdb_get_username(sampw)),
+                          talloc_strdup(sam3, pdb_get_fullname(sampw)),
+                          talloc_strdup(sam3, pdb_get_logon_script(sampw)),
+                          talloc_strdup(sam3, pdb_get_profile_path(sampw)),
+                          talloc_strdup(sam3, pdb_get_homedir(sampw)),
+                          talloc_strdup(sam3, pdb_get_dir_drive(sampw)),
+                          0, /* logon_count */
+                          0, /* bad_password_count */
+                          user_rid,
+                          group_rid,
+                          groups,
+                          NETLOGON_EXTRA_SIDS,
+                          user_session_key,
+                          my_name,
+                          talloc_strdup(sam3, pdb_get_domain(sampw)),
+                          sid,
+                          lm_session_key,
+                          pdb_get_acct_ctrl(sampw),
+                          0, /* sidcount */
+                          NULL); /* struct netr_SidAttr *sids */
+       ZERO_STRUCT(user_session_key);
+       ZERO_STRUCT(lm_session_key);
+
+       return NT_STATUS_OK;
+}
+
 /*******************************************************************
  inits a structure.
 ********************************************************************/
@@ -218,3 +403,20 @@ void init_netr_PasswordInfo(struct netr_PasswordInfo *r,
        r->lmpassword = lmpassword;
        r->ntpassword = ntpassword;
 }
+
+/*************************************************************************
+ inits a netr_CryptPassword structure
+ *************************************************************************/
+
+void init_netr_CryptPassword(const char *pwd,
+                            unsigned char session_key[16],
+                            struct netr_CryptPassword *pwd_buf)
+{
+       struct samr_CryptPassword password_buf;
+
+       encode_pw_buffer(password_buf.data, pwd, STR_UNICODE);
+
+       SamOEMhash(password_buf.data, session_key, 516);
+       memcpy(pwd_buf->data, password_buf.data, 512);
+       pwd_buf->length = IVAL(password_buf.data, 512);
+}