Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:dirkmueller:Factory
xrdp
xrdp-fate318398-change-expired-password.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xrdp-fate318398-change-expired-password.patch of Package xrdp
Index: xrdp-0.9.15/sesman/auth.h =================================================================== --- xrdp-0.9.15.orig/sesman/auth.h +++ xrdp-0.9.15/sesman/auth.h @@ -106,4 +106,6 @@ auth_check_pwd_chg(const char *user); int auth_change_pwd(const char *user, const char *newpwd); +int +auth_change_pwd_pam(char* user, char* pass, char* newpwd); #endif Index: xrdp-0.9.15/sesman/libscp/libscp_session.c =================================================================== --- xrdp-0.9.15.orig/sesman/libscp/libscp_session.c +++ xrdp-0.9.15/sesman/libscp/libscp_session.c @@ -76,6 +76,10 @@ scp_session_set_type(struct SCP_SESSION s->type = SCP_GW_AUTHENTICATION; break; + case SCP_GW_CHAUTHTOK: + s->type = SCP_GW_CHAUTHTOK; + break; + case SCP_SESSION_TYPE_MANAGE: s->type = SCP_SESSION_TYPE_MANAGE; s->mng = (struct SCP_MNG_DATA *)g_malloc(sizeof(struct SCP_MNG_DATA), 1); @@ -232,6 +236,32 @@ scp_session_set_password(struct SCP_SESS return 1; } + return 0; +} + +/*******************************************************************/ +int +scp_session_set_newpass(struct SCP_SESSION *s, char *str) +{ + if (0 == str) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_newpass: null newpass", __LINE__); + return 1; + } + + if (0 != s->newpass) + { + g_free(s->newpass); + } + + s->newpass = g_strdup(str); + + if (0 == s->newpass) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_newpass: strdup error", __LINE__); + return 1; + } + return 0; } Index: xrdp-0.9.15/sesman/libscp/libscp_types.h =================================================================== --- xrdp-0.9.15.orig/sesman/libscp/libscp_types.h +++ xrdp-0.9.15/sesman/libscp/libscp_types.h @@ -47,6 +47,7 @@ * XRDP sends this command to let sesman verify if the user is allowed * to use the gateway */ #define SCP_GW_AUTHENTICATION 0x04 +#define SCP_GW_CHAUTHTOK 0x05 #define SCP_ADDRESS_TYPE_IPV4 0x00 #define SCP_ADDRESS_TYPE_IPV6 0x01 @@ -81,6 +82,7 @@ struct SCP_SESSION char locale[18]; char* username; char* password; + char* newpass; char* hostname; tui8 addr_type; tui32 ipv4addr; Index: xrdp-0.9.15/sesman/libscp/libscp_v0.c =================================================================== --- xrdp-0.9.15.orig/sesman/libscp/libscp_v0.c +++ xrdp-0.9.15/sesman/libscp/libscp_v0.c @@ -367,9 +367,9 @@ scp_v0s_init_session(struct SCP_CONNECTI } } } - else if (code == SCP_GW_AUTHENTICATION) + else if (code == SCP_GW_AUTHENTICATION || code == SCP_GW_CHAUTHTOK) { - scp_session_set_type(session, SCP_GW_AUTHENTICATION); + scp_session_set_type(session, code); /* reading username */ if (!in_string16(c->in_s, buf, "username")) { @@ -383,6 +383,23 @@ scp_v0s_init_session(struct SCP_CONNECTI return SCP_SERVER_STATE_INTERNAL_ERR; } + if (code == SCP_GW_CHAUTHTOK) + { + /* reading new password */ + if (!in_string16(c->in_s, buf, "passwd")) + { + return SCP_SERVER_STATE_SIZE_ERR; + } + + if (0 != scp_session_set_newpass(session, buf)) + { + scp_session_destroy(session); + g_free(buf); + return SCP_SERVER_STATE_INTERNAL_ERR; + } + g_free(buf); + } + /* reading password */ if (!in_string16(c->in_s, buf, "passwd")) { @@ -512,12 +529,13 @@ scp_v0s_deny_connection(struct SCP_CONNE /******************************************************************************/ enum SCP_SERVER_STATES_E -scp_v0s_replyauthentication(struct SCP_CONNECTION *c, unsigned short int value) +scp_v0s_replyauthentication(struct SCP_CONNECTION *c, unsigned short int value, tui8 type) { out_uint32_be(c->out_s, 0); /* version */ out_uint32_be(c->out_s, 14); /* size */ /* cmd SCP_GW_AUTHENTICATION means authentication reply */ - out_uint16_be(c->out_s, SCP_GW_AUTHENTICATION); + /* cmd SCP_GW_CHAUTHTOK means chauthtok reply */ + out_uint16_be(c->out_s, type); out_uint16_be(c->out_s, value); /* reply code */ out_uint16_be(c->out_s, 0); /* dummy data */ s_mark_end(c->out_s); Index: xrdp-0.9.15/sesman/libscp/libscp_v0.h =================================================================== --- xrdp-0.9.15.orig/sesman/libscp/libscp_v0.h +++ xrdp-0.9.15/sesman/libscp/libscp_v0.h @@ -79,6 +79,6 @@ scp_v0s_deny_connection(struct SCP_CONNE * @return */ enum SCP_SERVER_STATES_E -scp_v0s_replyauthentication(struct SCP_CONNECTION* c, unsigned short int value); +scp_v0s_replyauthentication(struct SCP_CONNECTION* c, unsigned short int value, tui8 type); #endif Index: xrdp-0.9.15/sesman/scp_v0.c =================================================================== --- xrdp-0.9.15.orig/sesman/scp_v0.c +++ xrdp-0.9.15/sesman/scp_v0.c @@ -42,6 +42,13 @@ scp_v0_process(struct SCP_CONNECTION *c, int errorcode = 0; bool_t do_auth_end = 1; + if (s->type == SCP_GW_CHAUTHTOK) + { + errorcode = auth_change_pwd_pam(s->username, s->password, s->newpass); + scp_v0s_replyauthentication(c, errorcode, SCP_GW_CHAUTHTOK); + return ; + } + data = auth_userpass(s->username, s->password, &errorcode); if (s->type == SCP_GW_AUTHENTICATION) @@ -53,14 +60,14 @@ scp_v0_process(struct SCP_CONNECTION *c, if (1 == access_login_allowed(s->username)) { /* the user is member of the correct groups. */ - scp_v0s_replyauthentication(c, errorcode); + scp_v0s_replyauthentication(c, errorcode, SCP_GW_AUTHENTICATION); LOG(LOG_LEVEL_INFO, "Access permitted for user: %s", s->username); /* g_writeln("Connection allowed"); */ } else { - scp_v0s_replyauthentication(c, 32 + 3); /* all first 32 are reserved for PAM errors */ + scp_v0s_replyauthentication(c, 32 + 3, SCP_GW_AUTHENTICATION); /* all first 32 are reserved for PAM errors */ LOG(LOG_LEVEL_INFO, "Username okey but group problem for " "user: %s", s->username); /* g_writeln("user password ok, but group problem"); */ @@ -71,7 +78,7 @@ scp_v0_process(struct SCP_CONNECTION *c, /* g_writeln("username or password error"); */ LOG(LOG_LEVEL_INFO, "Username or password error for user: %s", s->username); - scp_v0s_replyauthentication(c, errorcode); + scp_v0s_replyauthentication(c, errorcode, SCP_GW_AUTHENTICATION); } } else if (data) Index: xrdp-0.9.15/sesman/verify_user_pam.c =================================================================== --- xrdp-0.9.15.orig/sesman/verify_user_pam.c +++ xrdp-0.9.15/sesman/verify_user_pam.c @@ -42,6 +42,7 @@ struct t_user_pass { char user[MAX_BUF]; char pass[MAX_BUF]; + char newpwd[MAX_BUF]; }; struct t_auth_info @@ -93,6 +94,55 @@ verify_pam_conv(int num_msg, const struc } /******************************************************************************/ +static int +chauth_pam_conv(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr) +{ + int i; + struct pam_response *reply; + struct t_user_pass *user_pass; + + reply = g_malloc(sizeof(struct pam_response) * num_msg, 1); + + for (i = 0; i < num_msg; i++) + { + switch (msg[i]->msg_style) + { + case PAM_PROMPT_ECHO_ON: /* username */ + user_pass = appdata_ptr; + reply[i].resp = g_strdup(user_pass->user); + reply[i].resp_retcode = PAM_SUCCESS; + break; + case PAM_PROMPT_ECHO_OFF: /* password */ + user_pass = appdata_ptr; + /* only prompt for old password starts with '(' + old pass: "(current) UNIX password:" + new pass: "New password:" + retype new pass: "Retype new password:" */ + if (*(msg[i]->msg) == '(') + { + reply[i].resp = g_strdup(user_pass->pass); + } + else + { + reply[i].resp = g_strdup(user_pass->newpwd); + } + reply[i].resp_retcode = PAM_SUCCESS; + break; + case PAM_TEXT_INFO: /* useless messages */ + break; + default: + g_printf("unknown in verify_pam_conv\r\n"); + g_free(reply); + return PAM_CONV_ERR; + } + } + + *resp = reply; + return PAM_SUCCESS; +} + +/******************************************************************************/ static void get_service_name(char *service_name) { @@ -110,6 +160,52 @@ get_service_name(char *service_name) } /******************************************************************************/ +/* returns boolean */ +/* update to the new pass */ +int +auth_change_pwd_pam(char *user, char *pass, char *newpwd) +{ + int error; + struct t_auth_info *auth_info; + char service_name[256]; + + get_service_name(service_name); + auth_info = g_malloc(sizeof(struct t_auth_info), 1); + g_strncpy(auth_info->user_pass.user, user, 255); + g_strncpy(auth_info->user_pass.pass, pass, 255); + g_strncpy(auth_info->user_pass.newpwd, newpwd, 255); + auth_info->pamc.conv = &chauth_pam_conv; + auth_info->pamc.appdata_ptr = &(auth_info->user_pass); + error = pam_start(service_name, 0, &(auth_info->pamc), &(auth_info->ph)); + + if (error != PAM_SUCCESS) + { + g_printf("pam_start failed: %s\r\n", pam_strerror(auth_info->ph, error)); + pam_end(auth_info->ph, error); + g_free(auth_info); + return error; + } + + error = pam_set_item(auth_info->ph, PAM_TTY, service_name); + if (error != PAM_SUCCESS) + { + g_printf("pam_set_item failed: %s\r\n", + pam_strerror(auth_info->ph, error)); + } + + error = pam_chauthtok(auth_info->ph, PAM_CHANGE_EXPIRED_AUTHTOK); + if (error != PAM_SUCCESS) + { + g_printf("pam_chauthtok failed: %s\r\n", + pam_strerror(auth_info->ph, error)); + pam_end(auth_info->ph, error); + g_free(auth_info); + return error; + } + return error; +} + +/******************************************************************************/ /* returns long, zero is no go Stores the detailed error code in the errorcode variable*/ Index: xrdp-0.9.15/xrdp/xrdp_login_wnd.c =================================================================== --- xrdp-0.9.15.orig/xrdp/xrdp_login_wnd.c +++ xrdp-0.9.15/xrdp/xrdp_login_wnd.c @@ -188,7 +188,14 @@ xrdp_wm_cancel_clicked(struct xrdp_bitma { if (wnd->wm != 0) { - if (wnd->wm->pro_layer != 0) + struct xrdp_bitmap *b1; + b1 = xrdp_bitmap_get_child_by_id(wnd, 201); + if (b1 != 0 ) + { + /* go back to login window when canceling new password creation */ + xrdp_wm_set_login_mode(wnd->wm, 0); + } + else if (wnd->wm->pro_layer != 0) { g_set_wait_obj(wnd->wm->pro_layer->self_term_event); } @@ -246,7 +253,29 @@ xrdp_wm_ok_clicked(struct xrdp_bitmap *w } else { - log_message(LOG_LEVEL_ERROR, "Combo is 0 - potential programming error"); + struct xrdp_bitmap *b1; + struct xrdp_bitmap *b2; + struct xrdp_bitmap *b3; + b1 = xrdp_bitmap_get_child_by_id(wnd, 201); + b2 = xrdp_bitmap_get_child_by_id(wnd, 203); + b3 = xrdp_bitmap_get_child_by_id(wnd, 250); + if (b1 != 0 && b2 != 0 && b3 != 0) + { + if (g_strlen(b1->caption1) > 0 && g_strncmp (b1->caption1, b2->caption1, 255) == 0) + { + list_add_item (wm->mm->login_names,(tbus)g_strdup("newpass")); + list_add_item (wm->mm->login_values,(tbus)g_strdup(b2->caption1)); + xrdp_wm_set_login_mode (wm, 22); + } + else + { + xrdp_wm_set_login_mode(wm, 20); + } + } + else + { + log_message(LOG_LEVEL_ERROR, "Window not recognized - potential programming error"); + } } return 0; @@ -546,6 +575,32 @@ xrdp_wm_login_notify(struct xrdp_bitmap return 0; } +/*****************************************************************************/ +/* change new password window events go here */ +static int +xrdp_wm_newpass_notify(struct xrdp_bitmap *wnd, + struct xrdp_bitmap *sender, + int msg, long param1, long param2) +{ + if (wnd->modal_dialog != 0 && msg != 100) + { + return 0; + } + + if (msg == 1) /* click */ + { + if (sender->id == 2) /* cancel button */ + { + xrdp_wm_cancel_clicked(wnd); + } + else if (sender->id == 3) /* ok button */ + { + xrdp_wm_ok_clicked(wnd); + } + } + return 0; +} + /******************************************************************************/ static int xrdp_wm_login_fill_in_combo(struct xrdp_wm *self, struct xrdp_bitmap *b) @@ -827,6 +882,103 @@ xrdp_login_wnd_create(struct xrdp_wm *se return 0; } + +/******************************************************************************/ +int +xrdp_newpass_wnd_create(struct xrdp_wm *self) +{ + struct xrdp_bitmap *but; + struct xrdp_cfg_globals *globals; + int i; + + globals = &self->xrdp_config->cfg_globals; + + self->newpass_window = xrdp_bitmap_create(globals->ls_width, globals->ls_height, self->screen->bpp, + WND_TYPE_WND, self); + list_add_item(self->screen->child_list, (long)self->newpass_window); + self->newpass_window->parent = self->screen; + self->newpass_window->owner = self->screen; + self->newpass_window->bg_color = globals->ls_bg_color; + + self->newpass_window->left = self->screen->width / 2 - + self->newpass_window->width / 2; + + self->newpass_window->top = self->screen->height / 2 - + self->newpass_window->height / 2; + + self->newpass_window->notify = xrdp_wm_newpass_notify; + + set_string(&self->newpass_window->caption1, "Input new password"); + + /* OK button */ + but = xrdp_bitmap_create(globals->ls_btn_ok_width, globals->ls_btn_ok_height, + self->screen->bpp, WND_TYPE_BUTTON, self); + list_add_item(self->newpass_window->child_list, (long)but); + but->parent = self->newpass_window; + but->owner = self->newpass_window; + but->left = globals->ls_btn_ok_x_pos; + but->top = globals->ls_btn_ok_y_pos; + but->id = 3; + set_string(&but->caption1, "OK"); + but->tab_stop = 1; + self->newpass_window->default_button = but; + + /* Cancel button */ + but = xrdp_bitmap_create(globals->ls_btn_cancel_width, + globals->ls_btn_cancel_height, self->screen->bpp, + WND_TYPE_BUTTON, self); + list_add_item(self->newpass_window->child_list, (long)but); + but->parent = self->newpass_window; + but->owner = self->newpass_window; + but->left = globals->ls_btn_cancel_x_pos; + but->top = globals->ls_btn_cancel_y_pos; + but->id = 2; + set_string(&but->caption1, "Cancel"); + but->tab_stop = 1; + self->newpass_window->esc_button = but; + + /* labels and edits */ + /* id starts between 200 and 249 */ + char captions [][256] = {"New Pass", "Confirm"}; + for (i = 0; i < 2; i++) + { + but = xrdp_bitmap_create(globals->ls_label_width, DEFAULT_EDIT_H, self->screen->bpp, + WND_TYPE_LABEL, self); + list_add_item(self->newpass_window->child_list, (long)but); + but->parent = self->newpass_window; + but->owner = self->newpass_window; + but->left = globals->ls_label_x_pos; + but->top = globals->ls_input_y_pos + (DEFAULT_COMBO_H +5) * i; + but->id = 200 + 2 * i; + set_string(&but->caption1, captions[i]); + + but = xrdp_bitmap_create(globals->ls_input_width, DEFAULT_EDIT_H, self->screen->bpp, + WND_TYPE_EDIT, self); + list_add_item(self->newpass_window->child_list, (long)but); + but->parent = self->newpass_window; + but->owner = self->newpass_window; + but->left = globals->ls_input_x_pos; + but->top = globals->ls_input_y_pos + (DEFAULT_COMBO_H +5) * i; + but->id = 201 + 2 * i; + but->pointer = 1; + but->tab_stop = 1; + but->caption1 = (char *)g_malloc(256, 1); + but->password_char = '*'; + } + /* error message label */ + but = xrdp_bitmap_create (300, DEFAULT_EDIT_H, self->screen->bpp, + WND_TYPE_LABEL, self); + list_add_item(self->newpass_window->child_list, (long)but); + but->parent = self->newpass_window; + but->owner = self->newpass_window; + but->left = globals->ls_label_x_pos; + but->top = globals->ls_input_y_pos + (DEFAULT_COMBO_H +5) * 2; + but->id = 250; + but->caption1 = (char *)g_malloc(256, 1); + set_string(&but->caption1, ""); + + return 0; +} /** * Load configuration from xrdp.ini file Index: xrdp-0.9.15/xrdp/xrdp_mm.c =================================================================== --- xrdp-0.9.15.orig/xrdp/xrdp_mm.c +++ xrdp-0.9.15/xrdp/xrdp_mm.c @@ -1787,7 +1787,7 @@ xrdp_mm_sesman_data_in(struct trans *tra /*********************************************************************/ /* return 0 on success */ static int -access_control(char *username, char *password, char *srv) +access_control(char *username, char *password, char *newpass, char *srv, int type) { int reply; int rec = 32+1; /* 32 is reserved for PAM failures this means connect failure */ @@ -1815,7 +1815,8 @@ access_control(char *username, char *pas make_stream(out_s); init_stream(out_s, 500); s_push_layer(out_s, channel_hdr, 8); - out_uint16_be(out_s, 4); /*0x04 means SCP_GW_AUTHENTICATION*/ + out_uint16_be(out_s, type); /*0x04 means SCP_GW_AUTHENTICATION*/ + /*0x05 means SCP_GW_CHAUTHTOK*/ index = g_strlen(username); out_uint16_be(out_s, index); out_uint8a(out_s, username, index); @@ -1823,6 +1824,14 @@ access_control(char *username, char *pas index = g_strlen(password); out_uint16_be(out_s, index); out_uint8a(out_s, password, index); + + if (type == 5) + { + index = g_strlen(newpass); + out_uint16_be(out_s, index); + out_uint8a(out_s, newpass, index); + } + s_mark_end(out_s); s_pop_layer(out_s, channel_hdr); out_uint32_be(out_s, 0); /* version */ @@ -1852,15 +1861,19 @@ access_control(char *username, char *pas in_uint16_be(in_s, pAM_errorcode); /* this variable holds the PAM error code if the variable is >32 it is a "invented" code */ in_uint16_be(in_s, dummy); - if (code != 4) /*0x04 means SCP_GW_AUTHENTICATION*/ + if (code == 4) /*0x04 means SCP_GW_AUTHENTICATION*/ { - log_message(LOG_LEVEL_ERROR, "Returned cmd code from " - "sesman is corrupt"); + rec = pAM_errorcode; /* here we read the reply from the access control */ } - else + else if (code == 5) /*0x05 means SCP_GW_CHAUTHTOK*/ { rec = pAM_errorcode; /* here we read the reply from the access control */ } + else + { + log_message(LOG_LEVEL_ERROR, "Returned cmd code from " + "sesman is corrupt"); + } } else { @@ -2178,7 +2191,7 @@ xrdp_mm_connect(struct xrdp_mm *self) char port[8]; char chansrvport[256]; #ifndef USE_NOPAM - int use_pam_auth = 0; + int use_pam_auth_explicit = 0; char pam_auth_sessionIP[256]; char pam_auth_password[256]; char pam_auth_username[256]; @@ -2218,7 +2231,7 @@ xrdp_mm_connect(struct xrdp_mm *self) #ifndef USE_NOPAM else if (g_strcasecmp(name, "pamusername") == 0) { - use_pam_auth = 1; + use_pam_auth_explicit = 1; g_strncpy(pam_auth_username, value, 255); } else if (g_strcasecmp(name, "pamsessionmng") == 0) @@ -2246,45 +2259,55 @@ xrdp_mm_connect(struct xrdp_mm *self) } #ifndef USE_NOPAM - if (use_pam_auth) - { - int reply; - char pam_error[128]; - const char *additionalError; - xrdp_wm_log_msg(self->wm, LOG_LEVEL_DEBUG, - "Please wait, we now perform access control..."); + int reply; + char pam_error[128]; + const char *additionalError; + xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "Please wait, we now perform access control..."); - /* g_writeln("we use pam modules to check if we can approve this user"); */ - if (!g_strncmp(pam_auth_username, "same", 255)) - { - log_message(LOG_LEVEL_DEBUG, "pamusername copied from username - same: %s", username); - g_strncpy(pam_auth_username, username, 255); - } + /* use pam either way, copy from normal user name when not explicitly inputed */ + if (use_pam_auth_explicit == 0) + { + log_message(LOG_LEVEL_DEBUG, "pam parameters not defined, copy from user input"); + g_strncpy(pam_auth_username, username, 255); + g_strncpy(pam_auth_password, password, 255); + g_strncpy(pam_auth_sessionIP, "127.0.0.1", 255); + } - if (!g_strncmp(pam_auth_password, "same", 255)) - { - log_message(LOG_LEVEL_DEBUG, "pam_auth_password copied from username - same: %s", password); - g_strncpy(pam_auth_password, password, 255); - } + if (!g_strncmp(pam_auth_username, "same", 255)) + { + log_message(LOG_LEVEL_DEBUG, "pamusername copied from username - same: %s", username); + g_strncpy(pam_auth_username, username, 255); + } - /* access_control return 0 on success */ - reply = access_control(pam_auth_username, pam_auth_password, pam_auth_sessionIP); + if (!g_strncmp(pam_auth_password, "same", 255)) + { + log_message(LOG_LEVEL_DEBUG, "pam_auth_password copied from password - same: %s", password); + g_strncpy(pam_auth_password, password, 255); + } - xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, - "Reply from access control: %s", - getPAMError(reply, pam_error, 127)); + /* access_control return 0 on success */ + reply = access_control(pam_auth_username, pam_auth_password, NULL, pam_auth_sessionIP, 4); + xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, + "Reply from access control: %s", + getPAMError(reply, pam_error, 127)); - additionalError = getPAMAdditionalErrorInfo(reply, self); - if (additionalError && additionalError[0]) - { - xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "%s", additionalError); - } + additionalError = getPAMAdditionalErrorInfo(reply, self); + if (additionalError && additionalError[0]) + { + xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "%s", additionalError); + } - if (reply != 0) + if (reply != 0) + { + /* show PAM errors */ + xrdp_wm_show_log(self->wm); + if (reply == PAM_NEW_AUTHTOK_REQD) { - rv = 1; - return rv; + /* show new password window */ + xrdp_wm_set_login_mode(self->wm, 20); } + rv = 1; + return rv; } #endif @@ -2380,6 +2403,59 @@ xrdp_mm_connect(struct xrdp_mm *self) return rv; } +/*****************************************************************************/ +/* return 0 on success */ +int +xrdp_mm_change_expired_password(struct xrdp_mm *self) +{ + int rv = -1; + int index; + int count; + int old_idx; + char *username; + char *password; + char *newpass; + char sessionIP[256]; + char *name; + char *value; + + old_idx = -1; + username = 0; + password = 0; + newpass = 0; + count = self->login_names->count; + + for (index = 0; index < count; index++) + { + name = (char *)list_get_item(self->login_names, index); + value = (char *)list_get_item(self->login_values, index); + + if (g_strcasecmp(name, "username") == 0) + { + username = value; + } + else if (g_strcasecmp(name, "password") == 0) + { + password = value; + old_idx = index; + } + else if (g_strcasecmp(name, "newpass") == 0) + { + newpass = value; + } + g_strncpy(sessionIP, "127.0.0.1", 255); + } + rv = access_control(username, password, newpass, sessionIP, 5); + if (rv == 0 && old_idx >= 0 && old_idx < count && password != 0) + { + list_remove_item (self->login_names, old_idx); + list_remove_item (self->login_values, old_idx); + list_add_item (self->login_names, (tbus)g_strdup("password")); + list_add_item (self->login_values, (tbus)g_strdup(newpass)); + } + return rv; +} + /*****************************************************************************/ int xrdp_mm_get_wait_objs(struct xrdp_mm *self, Index: xrdp-0.9.15/xrdp/xrdp_types.h =================================================================== --- xrdp-0.9.15.orig/xrdp/xrdp_types.h +++ xrdp-0.9.15/xrdp/xrdp_types.h @@ -332,6 +332,7 @@ struct xrdp_wm struct xrdp_cache* cache; int palette[256]; struct xrdp_bitmap* login_window; + struct xrdp_bitmap* newpass_window; /* generic colors */ int black; int grey; Index: xrdp-0.9.15/xrdp/xrdp_wm.c =================================================================== --- xrdp-0.9.15.orig/xrdp/xrdp_wm.c +++ xrdp-0.9.15/xrdp/xrdp_wm.c @@ -1997,6 +1997,34 @@ xrdp_wm_login_mode_changed(struct xrdp_w self->dragging = 0; xrdp_wm_set_login_mode(self, 11); } + else if (self->login_mode == 20) + { + /* keep log window open */ + if (self->log_wnd == 0) + { + xrdp_wm_delete_all_children(self); + } + /* show update expired password window */ + self->dragging = 0; + xrdp_newpass_wnd_create(self); + xrdp_bitmap_invalidate(self->screen, 0); + xrdp_wm_set_focused(self, self->newpass_window); + xrdp_wm_set_login_mode(self, 21); + } + else if (self->login_mode == 22) + { + /* do change expired password session */ + xrdp_wm_delete_all_children(self); + self->dragging = 0; + if (xrdp_mm_change_expired_password(self->mm) == 0) + { + xrdp_wm_set_login_mode(self, 2); /* with password updated, connect again */ + } + else + { + xrdp_wm_set_login_mode(self, 20); /* try to change password again */ + } + } return 0; } @@ -2041,11 +2069,19 @@ xrdp_wm_log_wnd_notify(struct xrdp_bitma xrdp_bitmap_invalidate(wm->screen, &rect); /* if module is gone, reset the session when ok is clicked */ + /* unless we are to update password */ if (wm->mm->mod_handle == 0) { /* make sure autologin is off */ wm->session->client_info->rdp_autologin = 0; - xrdp_wm_set_login_mode(wm, 0); /* reset session */ + if (wm->login_mode == 21) + { + xrdp_wm_set_login_mode(wm, 20); /* try update password again */ + } + else + { + xrdp_wm_set_login_mode(wm, 0); /* reset session */ + } } } } Index: xrdp-0.9.15/xrdp/xrdp.h =================================================================== --- xrdp-0.9.15.orig/xrdp/xrdp.h +++ xrdp-0.9.15/xrdp/xrdp.h @@ -358,6 +358,8 @@ int xrdp_login_wnd_create(struct xrdp_wm* self); int load_xrdp_config(struct xrdp_config *config, const char *xrdp_ini, int bpp); +int +xrdp_newpass_wnd_create(struct xrdp_wm *self); /* xrdp_bitmap_compress.c */ int @@ -392,6 +394,8 @@ xrdp_mm_check_wait_objs(struct xrdp_mm* int xrdp_mm_frame_ack(struct xrdp_mm *self, int frame_id); int +xrdp_mm_change_expired_password(struct xrdp_mm *self); +int server_begin_update(struct xrdp_mod* mod); int server_end_update(struct xrdp_mod* mod); Index: xrdp-0.9.15/sesman/libscp/libscp_session.h =================================================================== --- xrdp-0.9.15.orig/sesman/libscp/libscp_session.h +++ xrdp-0.9.15/sesman/libscp/libscp_session.h @@ -94,6 +94,9 @@ scp_session_set_errstr(struct SCP_SESSIO int scp_session_set_guid(struct SCP_SESSION *s, const tui8 *guid); +int +scp_session_set_newpass(struct SCP_SESSION *s, char *str); + /** * * @brief destroys a session object
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor