diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:49:22 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:49:22 +0000 |
commit | 6c29c43354706a933c0bc73a9c800bdfd1a9a827 (patch) | |
tree | 37ab6c9430469a3d73ea08c12cfeda668dcb1a34 /greeter | |
parent | fa5d4a38a4dae7f24cdf3b8650dd931294c0fdc6 (diff) |
XFree86 4.3.0.1xf86-4_3_0_1PRE_xf86-4_3_0_1
Diffstat (limited to 'greeter')
-rw-r--r-- | greeter/Login.c | 800 | ||||
-rw-r--r-- | greeter/Login.h | 39 | ||||
-rw-r--r-- | greeter/LoginP.h | 34 | ||||
-rw-r--r-- | greeter/greet.c | 174 | ||||
-rw-r--r-- | greeter/verify.c | 383 |
5 files changed, 1191 insertions, 239 deletions
diff --git a/greeter/Login.c b/greeter/Login.c index 7650774..df91b0d 100644 --- a/greeter/Login.c +++ b/greeter/Login.c @@ -26,6 +26,7 @@ other dealings in this Software without prior written authorization from The Open Group. */ +/* $XFree86: xc/programs/xdm/greeter/Login.c,v 3.16 2002/10/06 20:42:16 herrb Exp $ */ /* * xdm - display manager daemon @@ -37,17 +38,40 @@ from The Open Group. # include <X11/IntrinsicP.h> # include <X11/StringDefs.h> # include <X11/keysym.h> +# include <X11/DECkeysym.h> # include <X11/Xfuncs.h> # include <stdio.h> +#ifdef XPM +# include <time.h> +#endif /* XPM */ # include "dm.h" +# include "dm_error.h" # include "greet.h" # include "LoginP.h" +#ifdef XPM +#include <sys/stat.h> +#include <unistd.h> +#include <X11/Xlib.h> +#include <X11/xpm.h> +#include <X11/extensions/shape.h> +#include <X11/cursorfont.h> +#endif /* XPM */ + +#ifdef USE_XINERAMA +#include <X11/extensions/Xinerama.h> +#endif + +static void RedrawFail (LoginWidget w); +static void ResetLogin (LoginWidget w); +static void failTimeout (XtPointer client_data, XtIntervalId * id); + #define offset(field) XtOffsetOf(LoginRec, login.field) #define goffset(field) XtOffsetOf(WidgetRec, core.field) + static XtResource resources[] = { {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension), goffset(width), XtRImmediate, (XtPointer) 0}, @@ -65,6 +89,37 @@ static XtResource resources[] = { offset(greetpixel), XtRString, XtDefaultForeground}, {XtNfailColor, XtCForeground, XtRPixel, sizeof (Pixel), offset(failpixel), XtRString, XtDefaultForeground}, + +#ifdef XPM +/* added by Caolan McNamara */ + {XtNlastEventTime, XtCLastEventTime, XtRInt , sizeof (int), + offset(lastEventTime), XtRImmediate, (XtPointer)0}, +/* end (caolan) */ + +/* added by Ivan Griffin (ivan.griffin@ul.ie) */ + {XtNlogoFileName, XtCLogoFileName, XtRString, sizeof(char*), + offset(logoFileName), XtRImmediate, (XtPointer)0}, + {XtNuseShape, XtCUseShape, XtRBoolean, sizeof(Boolean), + offset(useShape), XtRImmediate, (XtPointer) True}, + {XtNlogoPadding, XtCLogoPadding, XtRInt, sizeof(int), + offset(logoPadding), XtRImmediate, (XtPointer) 5}, +/* end (ivan) */ + + +/* added by Amit Margalit */ + {XtNhiColor, XtCForeground, XtRPixel, sizeof (Pixel), + offset(hipixel), XtRString, XtDefaultForeground}, + {XtNshdColor, XtCForeground, XtRPixel, sizeof (Pixel), + offset(shdpixel), XtRString, XtDefaultForeground}, + {XtNframeWidth, XtCFrameWidth, XtRInt, sizeof(int), + offset(outframewidth), XtRImmediate, (XtPointer) 1}, + {XtNinnerFramesWidth, XtCFrameWidth, XtRInt, sizeof(int), + offset(inframeswidth), XtRImmediate, (XtPointer) 1}, + {XtNsepWidth, XtCFrameWidth, XtRInt, sizeof(int), + offset(sepwidth), XtRImmediate, (XtPointer) 1}, +/* end (amit) */ +#endif /* XPM */ + {XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *), offset (font), XtRString, "*-new century schoolbook-medium-r-normal-*-180-*"}, {XtNpromptFont, XtCFont, XtRFontStruct, sizeof (XFontStruct *), @@ -92,7 +147,11 @@ static XtResource resources[] = { {XtNsecureSession, XtCSecureSession, XtRBoolean, sizeof (Boolean), offset(secure_session), XtRImmediate, False }, {XtNallowAccess, XtCAllowAccess, XtRBoolean, sizeof (Boolean), - offset(allow_access), XtRImmediate, False } + offset(allow_access), XtRImmediate, False }, + {XtNallowNullPasswd, XtCAllowNullPasswd, XtRBoolean, sizeof (Boolean), + offset(allow_null_passwd), XtRImmediate, False}, + {XtNallowRootLogin, XtCAllowRootLogin, XtRBoolean, sizeof(Boolean), + offset(allow_root_login), XtRImmediate, (XtPointer) True} }; #undef offset @@ -113,22 +172,43 @@ static XtResource resources[] = { # define Y_INC(w) max (TEXT_Y_INC(w), PROMPT_Y_INC(w)) +#ifndef XPM # define LOGIN_PROMPT_W(w) (XTextWidth (w->login.promptFont,\ w->login.namePrompt,\ strlen (w->login.namePrompt))) +#else +# define LOGIN_PROMPT_W(w) (XTextWidth (w->login.promptFont,\ + w->login.namePrompt,\ + strlen (w->login.namePrompt)) + \ + w->login.inframeswidth) +#endif /* XPM */ +#ifndef XPM # define PASS_PROMPT_W(w) (XTextWidth (w->login.promptFont,\ w->login.passwdPrompt,\ strlen (w->login.passwdPrompt))) +#else +# define PASS_PROMPT_W(w) (XTextWidth (w->login.promptFont,\ + w->login.passwdPrompt,\ + strlen (w->login.passwdPrompt)) + \ + w->login.inframeswidth) +#endif /* XPM */ # define PROMPT_W(w) (max(LOGIN_PROMPT_W(w), PASS_PROMPT_W(w))) # define GREETING(w) ((w)->login.secure_session && !(w)->login.allow_access ?\ (w)->login.greeting : (w)->login.unsecure_greet) # define GREET_X(w) ((int)(w->core.width - XTextWidth (w->login.greetFont,\ GREETING(w), strlen (GREETING(w)))) / 2) # define GREET_Y(w) (GREETING(w)[0] ? 2 * GREET_Y_INC (w) : 0) +#ifndef XPM # define GREET_W(w) (max (XTextWidth (w->login.greetFont,\ w->login.greeting, strlen (w->login.greeting)), \ XTextWidth (w->login.greetFont,\ w->login.unsecure_greet, strlen (w->login.unsecure_greet)))) +#else +# define GREET_W(w) (max (XTextWidth (w->login.greetFont,\ + w->login.greeting, strlen (w->login.greeting)), \ + XTextWidth (w->login.greetFont,\ + w->login.unsecure_greet, strlen (w->login.unsecure_greet)))) + w->login.logoWidth + (2*w->login.logoPadding) +#endif /* XPM */ # define LOGIN_X(w) (2 * PROMPT_X_INC(w)) # define LOGIN_Y(w) (GREET_Y(w) + GREET_Y_INC(w) +\ w->login.greetFont->max_bounds.ascent + Y_INC(w)) @@ -136,7 +216,11 @@ static XtResource resources[] = { # define LOGIN_H(w) (3 * Y_INC(w) / 2) # define LOGIN_TEXT_X(w)(LOGIN_X(w) + PROMPT_W(w)) # define PASS_X(w) (LOGIN_X(w)) +#ifndef XPM # define PASS_Y(w) (LOGIN_Y(w) + 8 * Y_INC(w) / 5) +#else +# define PASS_Y(w) (LOGIN_Y(w) + 10 * Y_INC(w) / 5) +#endif /* XPM */ # define PASS_W(w) (LOGIN_W(w)) # define PASS_H(w) (LOGIN_H(w)) # define PASS_TEXT_X(w) (PASS_X(w) + PROMPT_W(w)) @@ -144,24 +228,25 @@ static XtResource resources[] = { w->login.fail, strlen (w->login.fail))) / 2) # define FAIL_Y(w) (PASS_Y(w) + 2 * FAIL_Y_INC (w) +\ w->login.failFont->max_bounds.ascent) +#ifndef XPM # define FAIL_W(w) (XTextWidth (w->login.failFont,\ w->login.fail, strlen (w->login.fail))) +#else +# define FAIL_W(w) (XTextWidth (w->login.failFont,\ + w->login.fail, strlen (w->login.fail))) + w->login.logoWidth + (2*w->login.logoPadding) +#endif /* XPM */ # define PAD_X(w) (2 * (LOGIN_X(w) + max (GREET_X_INC(w), FAIL_X_INC(w)))) # define PAD_Y(w) (max (max (Y_INC(w), GREET_Y_INC(w)),\ FAIL_Y_INC(w))) -static void Initialize(), Realize(), Destroy(), Redisplay(); -static Boolean SetValues(); -static void draw_it (); - -static int max (a,b) { return a > b ? a : b; } +#ifndef max +static int max (int a, int b) { return a > b ? a : b; } +#endif static void -EraseName (w, cursor) - LoginWidget w; - int cursor; +EraseName (LoginWidget w, int cursor) { int x; @@ -173,9 +258,7 @@ EraseName (w, cursor) } static void -DrawName (w, cursor) - LoginWidget w; - int cursor; +DrawName (LoginWidget w, int cursor) { int x; @@ -184,12 +267,16 @@ DrawName (w, cursor) x += XTextWidth (w->login.font, w->login.data.name, cursor); XDrawString (XtDisplay(w), XtWindow (w), w->login.textGC, x, LOGIN_Y(w), w->login.data.name + cursor, strlen (w->login.data.name + cursor)); + +#ifdef XPM + /*as good a place as any Caolan begin*/ + w->login.lastEventTime = time(NULL); + /*as good a place as any Caolan end*/ +#endif /* XPM */ } static void -realizeCursor (w, gc) - LoginWidget w; - GC gc; +realizeCursor (LoginWidget w, GC gc) { int x, y; int height, width; @@ -213,12 +300,31 @@ realizeCursor (w, gc) return; } XFillRectangle (XtDisplay (w), XtWindow (w), gc, +#ifndef XPM x, y - w->login.font->max_bounds.ascent, width, height); +#else + x, y+1 - w->login.font->max_bounds.ascent, width, height-1); + XDrawPoint (XtDisplay (w), XtWindow (w), gc, + x-1 , y - w->login.font->max_bounds.ascent); + XDrawPoint (XtDisplay (w), XtWindow (w), gc, + x+1 , y - w->login.font->max_bounds.ascent); + XDrawPoint (XtDisplay (w), XtWindow (w), gc, + x-1 , y - w->login.font->max_bounds.ascent+height); + XDrawPoint (XtDisplay (w), XtWindow (w), gc, + x+1 , y - w->login.font->max_bounds.ascent+height); + XDrawPoint (XtDisplay (w), XtWindow (w), gc, + x-2 , y - w->login.font->max_bounds.ascent); + XDrawPoint (XtDisplay (w), XtWindow (w), gc, + x+2 , y - w->login.font->max_bounds.ascent); + XDrawPoint (XtDisplay (w), XtWindow (w), gc, + x-2 , y - w->login.font->max_bounds.ascent+height); + XDrawPoint (XtDisplay (w), XtWindow (w), gc, + x+2 , y - w->login.font->max_bounds.ascent+height); +#endif /* XPM */ } static void -EraseFail (w) - LoginWidget w; +EraseFail (LoginWidget w) { int x = FAIL_X(w); int y = FAIL_Y(w); @@ -234,31 +340,26 @@ EraseFail (w) } static void -XorCursor (w) - LoginWidget w; +XorCursor (LoginWidget w) { realizeCursor (w, w->login.xorGC); } static void -RemoveFail (w) - LoginWidget w; +RemoveFail (LoginWidget w) { if (w->login.failUp) EraseFail (w); } static void -EraseCursor (w) - LoginWidget (w); +EraseCursor (LoginWidget w) { realizeCursor (w, w->login.bgGC); } /*ARGSUSED*/ -void failTimeout (client_data, id) - XtPointer client_data; - XtIntervalId * id; +static void failTimeout (XtPointer client_data, XtIntervalId * id) { LoginWidget w = (LoginWidget)client_data; @@ -266,8 +367,8 @@ void failTimeout (client_data, id) EraseFail (w); } -DrawFail (ctx) - Widget ctx; +void +DrawFail (Widget ctx) { LoginWidget w; @@ -285,8 +386,8 @@ DrawFail (ctx) } } -RedrawFail (w) - LoginWidget w; +static void +RedrawFail (LoginWidget w) { int x = FAIL_X(w); int y = FAIL_Y(w); @@ -298,13 +399,101 @@ RedrawFail (w) } static void -draw_it (w) - LoginWidget w; +draw_it (LoginWidget w) { +#ifdef XPM + int i,in_frame_x,in_login_y,in_pass_y,in_width,in_height; + int gr_line_x, gr_line_y, gr_line_w; +#endif /* XPM */ + EraseCursor (w); + +#ifdef XPM + if( (w->login.outframewidth) < 1 ) + w->login.outframewidth = 1; + for(i=1;i<=(w->login.outframewidth);i++) + { + XDrawLine(XtDisplay (w), XtWindow (w), w->login.hiGC, + i-1,i-1,w->core.width-i,i-1); + XDrawLine(XtDisplay (w), XtWindow (w), w->login.hiGC, + i-1,i-1,i-1,w->core.height-i); + XDrawLine(XtDisplay (w), XtWindow (w), w->login.shdGC, + w->core.width-i,i-1,w->core.width-i,w->core.height-i); + XDrawLine(XtDisplay (w), XtWindow (w), w->login.shdGC, + i-1,w->core.height-i,w->core.width-i,w->core.height-i); + } + + /* make separator line */ + gr_line_x = w->login.outframewidth + w->login.logoPadding; + gr_line_y = GREET_Y(w) + GREET_Y_INC(w); + gr_line_w = w->core.width - 2*(w->login.outframewidth) - + (w->login.logoWidth + 3*(w->login.logoPadding)); + + for(i=1;i<=(w->login.sepwidth);i++) + { + XDrawLine(XtDisplay (w), XtWindow (w), w->login.shdGC, + gr_line_x, gr_line_y + i-1, + gr_line_x+gr_line_w, gr_line_y + i-1); + XDrawLine(XtDisplay (w), XtWindow (w), w->login.hiGC, + gr_line_x, gr_line_y + 2*(w->login.inframeswidth) -i, + gr_line_x+gr_line_w, gr_line_y + 2*(w->login.inframeswidth) -i); + } + + in_frame_x = LOGIN_TEXT_X(w) - w->login.inframeswidth - 3; + in_login_y = LOGIN_Y(w) - w->login.inframeswidth - 1 - TEXT_Y_INC(w); + in_pass_y = PASS_Y(w) - w->login.inframeswidth - 1 - TEXT_Y_INC(w); + + in_width = LOGIN_W(w) - PROMPT_W(w) - + (w->login.logoWidth + 2*(w->login.logoPadding)); + in_height = LOGIN_H(w) + w->login.inframeswidth + 2; + + for(i=1;i<=(w->login.inframeswidth);i++) + { + /* Make top/left sides */ + XDrawLine(XtDisplay (w), XtWindow (w), w->login.shdGC, + in_frame_x + i-1, in_login_y + i-1, + in_frame_x + in_width-i, in_login_y + i-1); + + XDrawLine(XtDisplay (w), XtWindow (w), w->login.shdGC, + in_frame_x + i-1, in_login_y + i-1, + in_frame_x + i-1, in_login_y + in_height-i); + + XDrawLine(XtDisplay (w), XtWindow (w), w->login.hiGC, + in_frame_x + in_width-i, in_login_y + i-1, + in_frame_x + in_width-i, in_login_y + in_height-i); + + XDrawLine(XtDisplay (w), XtWindow (w), w->login.hiGC, + in_frame_x + i-1, in_login_y + in_height-i, + in_frame_x + in_width-i, in_login_y + in_height-i); + + /* Make bottom/right sides */ + XDrawLine(XtDisplay (w), XtWindow (w), w->login.shdGC, + in_frame_x + i-1, in_pass_y + i-1, + in_frame_x + in_width-i, in_pass_y + i-1); + + XDrawLine(XtDisplay (w), XtWindow (w), w->login.shdGC, + in_frame_x + i-1, in_pass_y + i-1, + in_frame_x + i-1, in_pass_y + in_height-i); + + XDrawLine(XtDisplay (w), XtWindow (w), w->login.hiGC, + in_frame_x + in_width-i, in_pass_y + i-1, + in_frame_x + in_width-i, in_pass_y + in_height-i); + + XDrawLine(XtDisplay (w), XtWindow (w), w->login.hiGC, + in_frame_x + i-1, in_pass_y + in_height-i, + in_frame_x + in_width-i, in_pass_y + in_height-i); + } +#endif /* XPM */ + if (GREETING(w)[0]) XDrawString (XtDisplay (w), XtWindow (w), w->login.greetGC, +#ifndef XPM GREET_X(w), GREET_Y(w), +#else + GREET_X(w) - + ((w->login.logoWidth/2) + w->login.logoPadding), + GREET_Y(w), +#endif /* XPM */ GREETING(w), strlen (GREETING(w))); XDrawString (XtDisplay (w), XtWindow (w), w->login.promptGC, LOGIN_X(w), LOGIN_Y(w), @@ -333,11 +522,7 @@ draw_it (w) /*ARGSUSED*/ static void -DeleteBackwardChar (ctxw, event, params, num_params) - Widget ctxw; - XEvent *event; - String *params; - Cardinal *num_params; +DeleteBackwardChar (Widget ctxw, XEvent *event, String *params, Cardinal *num_params) { LoginWidget ctx = (LoginWidget)ctxw; @@ -363,11 +548,7 @@ DeleteBackwardChar (ctxw, event, params, num_params) /*ARGSUSED*/ static void -DeleteForwardChar (ctxw, event, params, num_params) - Widget ctxw; - XEvent *event; - String *params; - Cardinal *num_params; +DeleteForwardChar (Widget ctxw, XEvent *event, String *params, Cardinal *num_params) { LoginWidget ctx = (LoginWidget)ctxw; @@ -394,11 +575,11 @@ DeleteForwardChar (ctxw, event, params, num_params) /*ARGSUSED*/ static void -MoveBackwardChar (ctxw, event, params, num_params) - Widget ctxw; - XEvent *event; - String *params; - Cardinal *num_params; +MoveBackwardChar ( + Widget ctxw, + XEvent *event, + String *params, + Cardinal *num_params) { LoginWidget ctx = (LoginWidget)ctxw; @@ -411,11 +592,11 @@ MoveBackwardChar (ctxw, event, params, num_params) /*ARGSUSED*/ static void -MoveForwardChar (ctxw, event, params, num_params) - Widget ctxw; - XEvent *event; - String *params; - Cardinal *num_params; +MoveForwardChar ( + Widget ctxw, + XEvent *event, + String *params, + Cardinal *num_params) { LoginWidget ctx = (LoginWidget)ctxw; @@ -436,11 +617,11 @@ MoveForwardChar (ctxw, event, params, num_params) /*ARGSUSED*/ static void -MoveToBegining (ctxw, event, params, num_params) - Widget ctxw; - XEvent *event; - String *params; - Cardinal *num_params; +MoveToBegining ( + Widget ctxw, + XEvent *event, + String *params, + Cardinal *num_params) { LoginWidget ctx = (LoginWidget)ctxw; @@ -452,11 +633,11 @@ MoveToBegining (ctxw, event, params, num_params) /*ARGSUSED*/ static void -MoveToEnd (ctxw, event, params, num_params) - Widget ctxw; - XEvent *event; - String *params; - Cardinal *num_params; +MoveToEnd ( + Widget ctxw, + XEvent *event, + String *params, + Cardinal *num_params) { LoginWidget ctx = (LoginWidget)ctxw; @@ -475,11 +656,11 @@ MoveToEnd (ctxw, event, params, num_params) /*ARGSUSED*/ static void -EraseToEndOfLine (ctxw, event, params, num_params) - Widget ctxw; - XEvent *event; - String *params; - Cardinal *num_params; +EraseToEndOfLine ( + Widget ctxw, + XEvent *event, + String *params, + Cardinal *num_params) { LoginWidget ctx = (LoginWidget)ctxw; @@ -499,11 +680,11 @@ EraseToEndOfLine (ctxw, event, params, num_params) /*ARGSUSED*/ static void -EraseLine (ctxw, event, params, num_params) - Widget ctxw; - XEvent *event; - String *params; - Cardinal *num_params; +EraseLine ( + Widget ctxw, + XEvent *event, + String *params, + Cardinal *num_params) { MoveToBegining (ctxw, event, params, num_params); EraseToEndOfLine (ctxw, event, params, num_params); @@ -511,11 +692,11 @@ EraseLine (ctxw, event, params, num_params) /*ARGSUSED*/ static void -FinishField (ctxw, event, params, num_params) - Widget ctxw; - XEvent *event; - String *params; - Cardinal *num_params; +FinishField ( + Widget ctxw, + XEvent *event, + String *params, + Cardinal *num_params) { LoginWidget ctx = (LoginWidget)ctxw; @@ -535,13 +716,36 @@ FinishField (ctxw, event, params, num_params) XorCursor (ctx); } +#ifdef XPM /*ARGSUSED*/ static void -AllowAccess (ctxw, event, params, num_params) - Widget ctxw; - XEvent *event; - String *params; - Cardinal *num_params; +TabField(Widget ctxw, XEvent *event, String *params, Cardinal *num_params) +{ + LoginWidget ctx = (LoginWidget)ctxw; + + XorCursor (ctx); + RemoveFail (ctx); + switch (ctx->login.state) { + case GET_NAME: + ctx->login.state = GET_PASSWD; + ctx->login.cursor = 0; + break; + case GET_PASSWD: + ctx->login.state = GET_NAME; + ctx->login.cursor = 0; + break; + } + XorCursor (ctx); +} +#endif /* XPM */ + +/*ARGSUSED*/ +static void +AllowAccess ( + Widget ctxw, + XEvent *event, + String *params, + Cardinal *num_params) { LoginWidget ctx = (LoginWidget)ctxw; Arg arglist[1]; @@ -556,11 +760,11 @@ AllowAccess (ctxw, event, params, num_params) /*ARGSUSED*/ static void -SetSessionArgument (ctxw, event, params, num_params) - Widget ctxw; - XEvent *event; - String *params; - Cardinal *num_params; +SetSessionArgument ( + Widget ctxw, + XEvent *event, + String *params, + Cardinal *num_params) { LoginWidget ctx = (LoginWidget)ctxw; @@ -579,11 +783,11 @@ SetSessionArgument (ctxw, event, params, num_params) /*ARGSUSED*/ static void -RestartSession (ctxw, event, params, num_params) - Widget ctxw; - XEvent *event; - String *params; - Cardinal *num_params; +RestartSession ( + Widget ctxw, + XEvent *event, + String *params, + Cardinal *num_params) { LoginWidget ctx = (LoginWidget)ctxw; @@ -597,11 +801,11 @@ RestartSession (ctxw, event, params, num_params) /*ARGSUSED*/ static void -AbortSession (ctxw, event, params, num_params) - Widget ctxw; - XEvent *event; - String *params; - Cardinal *num_params; +AbortSession ( + Widget ctxw, + XEvent *event, + String *params, + Cardinal *num_params) { LoginWidget ctx = (LoginWidget)ctxw; @@ -615,11 +819,11 @@ AbortSession (ctxw, event, params, num_params) /*ARGSUSED*/ static void -AbortDisplay (ctxw, event, params, num_params) - Widget ctxw; - XEvent *event; - String *params; - Cardinal *num_params; +AbortDisplay ( + Widget ctxw, + XEvent *event, + String *params, + Cardinal *num_params) { LoginWidget ctx = (LoginWidget)ctxw; @@ -631,8 +835,8 @@ AbortDisplay (ctxw, event, params, num_params) XorCursor (ctx); } -ResetLogin (w) - LoginWidget w; +static void +ResetLogin (LoginWidget w) { EraseName (w, 0); w->login.cursor = 0; @@ -641,30 +845,138 @@ ResetLogin (w) w->login.state = GET_NAME; } +static void +InitI18N(Widget ctxw) +{ + LoginWidget ctx = (LoginWidget)ctxw; + XIM xim = (XIM) NULL; + char *p; + + ctx->login.xic = (XIC) NULL; + + if ((p = XSetLocaleModifiers("@im=none")) != NULL && *p) + xim = XOpenIM(XtDisplay(ctx), NULL, NULL, NULL); + + if (!xim) { + LogError("Failed to open input method\n"); + return; + } + + ctx->login.xic = XCreateIC(xim, + XNInputStyle, (XIMPreeditNothing|XIMStatusNothing), + XNClientWindow, ctx->core.window, + XNFocusWindow, ctx->core.window, NULL); + + if (!ctx->login.xic) { + LogError("Failed to create input context\n"); + XCloseIM(xim); + } + return; +} + /* ARGSUSED */ static void -InsertChar (ctxw, event, params, num_params) - Widget ctxw; - XEvent *event; - String *params; - Cardinal *num_params; +InsertChar ( + Widget ctxw, + XEvent *event, + String *params, + Cardinal *num_params) { LoginWidget ctx = (LoginWidget)ctxw; char strbuf[128]; +#ifndef XPM int len; - - len = XLookupString (&event->xkey, strbuf, sizeof (strbuf), 0, 0); +#else + int len,pixels; +#endif /* XPM */ + KeySym keysym = 0; + + if (ctx->login.xic) { + static Status status; + len = XmbLookupString(ctx->login.xic, &event->xkey, strbuf, + sizeof (strbuf), &keysym, &status); + } else { + static XComposeStatus compose_status = {NULL, 0}; + len = XLookupString (&event->xkey, strbuf, sizeof (strbuf), + &keysym, &compose_status); + } strbuf[len] = '\0'; + +#ifdef XPM + pixels = 3 + ctx->login.font->max_bounds.width * len + + XTextWidth(ctx->login.font, + ctx->login.data.name, + strlen(ctx->login.data.name)); + /* pixels to be added */ +#endif /* XPM */ + + /* + * Note: You can override this default key handling + * by the settings in the translation table + * loginActionsTable at the end of this file. + */ + switch (keysym) { + case XK_Return: + case XK_KP_Enter: + case XK_Linefeed: + case XK_Execute: + FinishField(ctxw, event, params, num_params); + return; + case XK_BackSpace: + DeleteBackwardChar(ctxw, event, params, num_params); + return; + case XK_Delete: + case XK_KP_Delete: + case DXK_Remove: + /* Sorry, it's not a telex machine, it's a terminal */ + DeleteForwardChar(ctxw, event, params, num_params); + return; + case XK_Left: + case XK_KP_Left: + MoveBackwardChar(ctxw, event, params, num_params); + return; + case XK_Right: + case XK_KP_Right: + MoveForwardChar(ctxw, event, params, num_params); + return; + case XK_End: + case XK_KP_End: + MoveToEnd(ctxw, event, params, num_params); + return; + case XK_Home: + case XK_KP_Home: + MoveToBegining(ctxw, event, params, num_params); + return; + default: + if (len == 0) { + if (!IsModifierKey(keysym)) /* it's not a modifier */ + XBell(XtDisplay(ctxw), 60); + return; + } else + break; + } + switch (ctx->login.state) { case GET_NAME: +#ifndef XPM if (len + (int)strlen(ctx->login.data.name) >= NAME_LEN - 1) +#else + if ( + (len + (int)strlen(ctx->login.data.name) >= NAME_LEN - 1)/* && + (pixels <= LOGIN_W(ctx) - PROMPT_W(ctx))*/ + ) +#endif /* XPM */ len = NAME_LEN - strlen(ctx->login.data.name) - 2; case GET_PASSWD: - if (len + (int)strlen(ctx->login.data.passwd) >= NAME_LEN - 1) - len = NAME_LEN - strlen(ctx->login.data.passwd) - 2; + if (len + (int)strlen(ctx->login.data.passwd) >= PASSWORD_LEN - 1) + len = PASSWORD_LEN - strlen(ctx->login.data.passwd) - 2; } +#ifndef XPM if (len == 0) +#else + if (len == 0 || pixels >= LOGIN_W(ctx) - PROMPT_W(ctx)) +#endif /* XPM */ return; XorCursor (ctx); RemoveFail (ctx); @@ -684,22 +996,45 @@ InsertChar (ctxw, event, params, num_params) strlen (ctx->login.data.passwd + ctx->login.cursor) + 1); memmove( ctx->login.data.passwd + ctx->login.cursor, strbuf, len); ctx->login.cursor += len; + +#ifdef XPM + /*as good a place as any Caolan begin*/ + ctx->login.lastEventTime = time(NULL); + /*as good a place as any Caolan end*/ +#endif /* XPM */ break; } XorCursor (ctx); } /* ARGSUSED */ -static void Initialize (greq, gnew, args, num_args) - Widget greq, gnew; - ArgList args; - Cardinal *num_args; +static void Initialize ( + Widget greq, + Widget gnew, + ArgList args, + Cardinal *num_args) { LoginWidget w = (LoginWidget)gnew; XtGCMask valuemask, xvaluemask; XGCValues myXGCV; Arg position[2]; Position x, y; +#ifdef USE_XINERAMA + XineramaScreenInfo *screens; + int s_num; +#endif + +#ifdef XPM + myXGCV.foreground = w->login.hipixel; + myXGCV.background = w->core.background_pixel; + valuemask = GCForeground | GCBackground; + w->login.hiGC = XtGetGC(gnew, valuemask, &myXGCV); + + myXGCV.foreground = w->login.shdpixel; + myXGCV.background = w->core.background_pixel; + valuemask = GCForeground | GCBackground; + w->login.shdGC = XtGetGC(gnew, valuemask, &myXGCV); +#endif /* XPM */ myXGCV.foreground = w->login.textpixel; myXGCV.background = w->core.background_pixel; @@ -756,6 +1091,55 @@ static void Initialize (greq, gnew, args, num_args) myXGCV.font = w->login.failFont->fid; w->login.failGC = XtGetGC (gnew, xvaluemask, &myXGCV); +#ifdef XPM + w->login.logoValid = False; + + if (NULL != w->login.logoFileName) + { + XpmAttributes myAttributes = { 0 }; + Window tmpWindow = { 0 }; + struct stat myBuffer = { 0 }; + unsigned int myPixmapDepth = 0; + + if (0 != stat(w->login.logoFileName, &myBuffer)) + { + LogError("Unable to stat() pixmap file %s\n", + w->login.logoFileName); + w->login.logoValid = False; + goto SkipXpmLoad; + } + else + + myAttributes.valuemask |= XpmReturnPixels; + myAttributes.valuemask |= XpmReturnExtensions; + + XpmReadFileToPixmap(XtDisplay(w), /* display */ + RootWindowOfScreen(XtScreen(w)), /* window */ + w->login.logoFileName, /* XPM filename */ + &(w->login.logoPixmap), /* pixmap */ + &(w->login.logoMask), /* pixmap mask */ + &myAttributes); /* XPM attributes */ + w->login.logoValid = True; + + XGetGeometry(XtDisplay(w), w->login.logoPixmap, + &tmpWindow, + &(w->login.logoX), + &(w->login.logoY), + &(w->login.logoWidth), + &(w->login.logoHeight), + &(w->login.logoBorderWidth), + &myPixmapDepth); + } else { + w->login.logoX = 0; + w->login.logoY = 0; + w->login.logoWidth = 0; + w->login.logoHeight = 0; + w->login.logoBorderWidth = 0; + } + + +SkipXpmLoad: +#endif /* XPM */ w->login.data.name[0] = '\0'; w->login.data.passwd[0] = '\0'; w->login.state = GET_NAME; @@ -767,55 +1151,148 @@ static void Initialize (greq, gnew, args, num_args) int fy = FAIL_Y(w); int pady = PAD_Y(w); +#ifndef XPM w->core.height = fy + pady; /* for stupid compilers */ +#else +/* w->core.height = fy + pady; * for stupid compilers */ + + w->core.height = max(fy + pady, + (w->login.logoHeight + (2*w->login.logoPadding)) + pady); + +#endif /* XPM */ + } +#ifdef USE_XINERAMA + if ( + XineramaIsActive(XtDisplay(w)) && + (screens = XineramaQueryScreens(XtDisplay(w), &s_num)) != NULL + ) + { + if ((x = w->core.x) == -1) + x = screens[0].x_org + (int)(screens[0].width - w->core.width) / 2; + if ((y = w->core.y) == -1) + y = screens[0].y_org + (int)(screens[0].height - w->core.height) / 3; + + XFree(screens); + } + else +#endif + { + if ((x = w->core.x) == -1) + x = (int)(XWidthOfScreen (XtScreen (w)) - w->core.width) / 2; + if ((y = w->core.y) == -1) + y = (int)(XHeightOfScreen (XtScreen (w)) - w->core.height) / 3; } - if ((x = w->core.x) == -1) - x = (int)(XWidthOfScreen (XtScreen (w)) - w->core.width) / 2; - if ((y = w->core.y) == -1) - y = (int)(XHeightOfScreen (XtScreen (w)) - w->core.height) / 3; XtSetArg (position[0], XtNx, x); XtSetArg (position[1], XtNy, y); XtSetValues (XtParent (w), position, (Cardinal) 2); } -static void Realize (gw, valueMask, attrs) - Widget gw; - XtValueMask *valueMask; - XSetWindowAttributes *attrs; +static void Realize ( + Widget gw, + XtValueMask *valueMask, + XSetWindowAttributes *attrs) { +#ifdef XPM + LoginWidget w = (LoginWidget) gw; + Cursor cursor; +#endif /* XPM */ XtCreateWindow( gw, (unsigned)InputOutput, (Visual *)CopyFromParent, *valueMask, attrs ); + InitI18N(gw); +#ifdef XPM + cursor = XCreateFontCursor(XtDisplay(gw), XC_left_ptr); + XDefineCursor(XtDisplay(gw), XtWindow(gw), cursor); + + /* + * Check if Pixmap was valid + */ + if (True == w->login.logoValid) + { + /* + * Create pixmap window + */ + { + unsigned long valueMask = CWBackPixel | CWBackPixmap; + XSetWindowAttributes windowAttributes = { 0 }; + + windowAttributes.background_pixel = w->core.background_pixel; + windowAttributes.background_pixmap = None; + + w->login.logoWindow = XCreateWindow(XtDisplay(w), + XtWindow(w), + w->core.width - w->login.outframewidth - + w->login.logoWidth - w->login.logoPadding, + (w->core.height - w->login.logoHeight) /2, + w->login.logoWidth, w->login.logoHeight, 0, + CopyFromParent, InputOutput, CopyFromParent, + valueMask, &windowAttributes); + } + + /* + * check if we can use shape extension + */ + if (True == w->login.useShape) + { + int foo, bar; + + if (XShapeQueryExtension(XtDisplay(w), &foo, &bar) == TRUE) + { + XShapeCombineMask(XtDisplay(w), w->login.logoWindow, + ShapeBounding, w->login.logoX, w->login.logoY, + w->login.logoMask, ShapeSet); + } + } + + XSetWindowBackgroundPixmap(XtDisplay(w), w->login.logoWindow, + w->login.logoPixmap); + XMapWindow(XtDisplay(w), w->login.logoWindow); + } +#endif /* XPM */ } -static void Destroy (gw) - Widget gw; +static void Destroy (Widget gw) { LoginWidget w = (LoginWidget)gw; bzero (w->login.data.name, NAME_LEN); - bzero (w->login.data.passwd, NAME_LEN); + bzero (w->login.data.passwd, PASSWORD_LEN); XtReleaseGC(gw, w->login.textGC); XtReleaseGC(gw, w->login.bgGC); XtReleaseGC(gw, w->login.xorGC); XtReleaseGC(gw, w->login.promptGC); XtReleaseGC(gw, w->login.greetGC); XtReleaseGC(gw, w->login.failGC); +#ifdef XPM + XtReleaseGC(gw, w->login.hiGC); + XtReleaseGC(gw, w->login.shdGC); + + if (True == w->login.logoValid) + { + if (w->login.logoPixmap != 0) + XFreePixmap(XtDisplay(w), w->login.logoPixmap); + + if (w->login.logoMask != 0) + XFreePixmap(XtDisplay(w), w->login.logoMask); + } +#endif /* XPM */ } /* ARGSUSED */ -static void Redisplay(gw, event, region) - Widget gw; - XEvent *event; - Region region; +static void Redisplay( + Widget gw, + XEvent *event, + Region region) { draw_it ((LoginWidget) gw); } /*ARGSUSED*/ -static Boolean SetValues (current, request, new, args, num_args) - Widget current, request, new; - ArgList args; - Cardinal *num_args; +static Boolean SetValues ( + Widget current, + Widget request, + Widget new, + ArgList args, + Cardinal *num_args) { LoginWidget currentL, newL; @@ -827,24 +1304,32 @@ static Boolean SetValues (current, request, new, args, num_args) } char defaultLoginTranslations [] = -"\ -Ctrl<Key>H: delete-previous-character() \n\ -Ctrl<Key>D: delete-character() \n\ -Ctrl<Key>B: move-backward-character() \n\ -Ctrl<Key>F: move-forward-character() \n\ -Ctrl<Key>A: move-to-begining() \n\ -Ctrl<Key>E: move-to-end() \n\ -Ctrl<Key>K: erase-to-end-of-line() \n\ -Ctrl<Key>U: erase-line() \n\ -Ctrl<Key>X: erase-line() \n\ -Ctrl<Key>C: restart-session() \n\ -Ctrl<Key>\\\\: abort-session() \n\ -:Ctrl<Key>plus: allow-all-access() \n\ -<Key>BackSpace: delete-previous-character() \n\ -<Key>Delete: delete-previous-character() \n\ -<Key>Return: finish-field() \n\ -<Key>: insert-char() \ -"; +"Ctrl<Key>H: delete-previous-character() \n" +"Ctrl<Key>D: delete-character() \n" +"Ctrl<Key>B: move-backward-character() \n" +"Ctrl<Key>F: move-forward-character() \n" +"Ctrl<Key>A: move-to-begining() \n" +"Ctrl<Key>E: move-to-end() \n" +"Ctrl<Key>K: erase-to-end-of-line() \n" +"Ctrl<Key>U: erase-line() \n" +"Ctrl<Key>X: erase-line() \n" +"Ctrl<Key>C: restart-session() \n" +"Ctrl<Key>\\\\: abort-session() \n" +":Ctrl<Key>plus: allow-all-access() \n" +"<Key>BackSpace: delete-previous-character() \n" +#ifdef linux +"<Key>Delete: delete-character() \n" +#else +"<Key>Delete: delete-previous-character() \n" +#endif +"<Key>Return: finish-field() \n" +#ifndef XPM +"<KeyPress>: insert-char()" +#else +"<Key>Tab: tab-field() \n" +"<KeyPress>: insert-char()" +#endif /* XPM */ +; XtActionsRec loginActionsTable [] = { {"delete-previous-character", DeleteBackwardChar}, @@ -856,6 +1341,9 @@ XtActionsRec loginActionsTable [] = { {"erase-to-end-of-line", EraseToEndOfLine}, {"erase-line", EraseLine}, {"finish-field", FinishField}, +#ifdef XPM + {"tab-field", TabField}, +#endif /* XPM */ {"abort-session", AbortSession}, {"abort-display", AbortDisplay}, {"restart-session", RestartSession}, @@ -889,7 +1377,11 @@ LoginClassRec loginClassRec = { /* expose */ Redisplay, /* set_values */ SetValues, /* set_values_hook */ NULL, +#ifndef XPM /* set_values_almost */ NULL, +#else + /* set_values_almost */ XtInheritSetValuesAlmost, +#endif /* XPM */ /* get_values_hook */ NULL, /* accept_focus */ NULL, /* version */ XtVersion, diff --git a/greeter/Login.h b/greeter/Login.h index d2b88f4..08578f3 100644 --- a/greeter/Login.h +++ b/greeter/Login.h @@ -26,6 +26,7 @@ other dealings in this Software without prior written authorization from The Open Group. */ +/* $XFree86: xc/programs/xdm/greeter/Login.h,v 3.7 2002/10/06 20:42:16 herrb Exp $ */ /* * xdm - display manager daemon @@ -74,7 +75,32 @@ from The Open Group. # define XtNsessionArgument "sessionArgument" # define XtNsecureSession "secureSession" # define XtNallowAccess "allowAccess" - +# define XtNallowNullPasswd "allowNullPasswd" +# define XtNallowRootLogin "allowRootLogin" + +#ifdef XPM +/* added by Amit Margalit Oct 1996 */ +# define XtNhiColor "hiColor" +# define XtNshdColor "shdColor" +# define XtNframeWidth "frameWidth" +# define XtNinnerFramesWidth "innerFramesWidth" +# define XtNsepWidth "sepWidth" + +/* caolan begin */ +#define XtNlastEventTime "lastEventTime" +#define XtCLastEventTime "LastEventTime" +/* caolan end */ + +#define XtNuseShape "useShape" +#define XtCUseShape "UseShape" +#define XtNlogoFileName "logoFileName" +#define XtCLogoFileName "LogoFileName" +#define XtNlogoPadding "logoPadding" +#define XtCLogoPadding "LogoPadding" + +# define XtCFrameWidth "FrameWidth" + +#endif /* XPM */ # define XtCGreeting "Greeting" # define XtCNamePrompt "NamePrompt" # define XtCPasswdPrompt "PasswdPrompt" @@ -83,13 +109,22 @@ from The Open Group. # define XtCSessionArgument "SessionArgument" # define XtCSecureSession "SecureSession" # define XtCAllowAccess "AllowAccess" +# define XtCAllowNullPasswd "AllowNullPasswd" +# define XtCAllowRootLogin "AllowRootLogin" /* notifyDone interface definition */ +#ifndef __OpenBSD__ #define NAME_LEN 32 +#define PASSWORD_LEN 32 +#else +#include <pwd.h> +#define NAME_LEN (_PW_NAME_LEN + 2) +#define PASSWORD_LEN (_PASSWORD_LEN + 2) +#endif typedef struct _LoginData { - char name[NAME_LEN], passwd[NAME_LEN]; + char name[NAME_LEN], passwd[PASSWORD_LEN]; } LoginData; # define NOTIFY_OK 0 diff --git a/greeter/LoginP.h b/greeter/LoginP.h index 8a8f467..0f88d79 100644 --- a/greeter/LoginP.h +++ b/greeter/LoginP.h @@ -26,6 +26,7 @@ other dealings in this Software without prior written authorization from The Open Group. */ +/* $XFree86: xc/programs/xdm/greeter/LoginP.h,v 3.8 2001/12/14 20:01:29 dawes Exp $ */ /* * xdm - display manager daemon @@ -37,23 +38,36 @@ from The Open Group. #include "Login.h" #include <X11/CoreP.h> +#ifdef XPM +#include <X11/Xlib.h> +#endif /* XPM */ #define GET_NAME 0 #define GET_PASSWD 1 #define DONE 2 +typedef void (*LoginFunc)(LoginWidget, LoginData *, int); + /* New fields for the login widget instance record */ typedef struct { Pixel textpixel; /* foreground pixel */ Pixel promptpixel; /* prompt pixel */ Pixel greetpixel; /* greeting pixel */ Pixel failpixel; /* failure pixel */ +#ifdef XPM + Pixel hipixel; /* frame hilite pixel */ + Pixel shdpixel; /* shadow frame pixel */ +#endif /* XPM */ GC textGC; /* pointer to GraphicsContext */ GC bgGC; /* pointer to GraphicsContext */ GC xorGC; /* pointer to GraphicsContext */ GC promptGC; GC greetGC; GC failGC; +#ifdef XPM + GC hiGC; /* for hilight part of frame */ + GC shdGC; /* for shaded part of frame */ +#endif /* XPM */ char *greeting; /* greeting */ char *unsecure_greet;/* message displayed when insecure */ char *namePrompt; /* name prompt */ @@ -68,11 +82,29 @@ typedef struct { int failUp; /* failure message displayed */ LoginData data; /* name/passwd */ char *sessionArg; /* argument passed to session */ - void (*notify_done)();/* proc to call when done */ + LoginFunc notify_done; /* proc to call when done */ int failTimeout; /* seconds til drop fail msg */ XtIntervalId interval_id; /* drop fail message note */ Boolean secure_session; /* session is secured */ Boolean allow_access; /* disable access control on login */ + Boolean allow_null_passwd; /* allow null password on login */ + Boolean allow_root_login; /* allow root login */ + XIC xic; /* input method of input context */ +#ifdef XPM + /*caolan begin*/ + int lastEventTime; + /*caolan end*/ + int outframewidth; /* outer frame thickness */ + int inframeswidth; /* inner frames thickness */ + int sepwidth; /* width of separator line */ + + char *logoFileName; + unsigned int logoWidth, logoHeight, logoPadding, logoBorderWidth; + int logoX, logoY; + Window logoWindow; + Boolean useShape, logoValid; + Pixmap logoPixmap, logoMask; +#endif /* XPM */ } LoginPart; /* Full instance record declaration */ diff --git a/greeter/greet.c b/greeter/greet.c index 93c64a6..5af88e8 100644 --- a/greeter/greet.c +++ b/greeter/greet.c @@ -26,6 +26,7 @@ other dealings in this Software without prior written authorization from The Open Group. */ +/* $XFree86: xc/programs/xdm/greeter/greet.c,v 3.16 2002/10/06 20:42:16 herrb Exp $ */ /* * xdm - display manager daemon @@ -40,42 +41,63 @@ from The Open Group. #include <X11/Shell.h> #include <X11/XKBlib.h> +#ifdef USE_XINERAMA +#include <X11/extensions/Xinerama.h> +#endif + #include "dm.h" +#include "dm_error.h" #include "greet.h" #include "Login.h" -#if GREET_LIB +#ifdef __OpenBSD__ +#include <syslog.h> +#endif + +#if defined(SECURE_RPC) && defined(sun) +/* Go figure, there's no getdomainname() prototype available */ +extern int getdomainname(char *name, size_t len); +#endif + +#ifdef GREET_LIB /* * Function pointers filled in by the initial call ito the library */ -int (*__xdm_PingServer)() = NULL; -int (*__xdm_SessionPingFailed)() = NULL; -int (*__xdm_Debug)() = NULL; -int (*__xdm_RegisterCloseOnFork)() = NULL; -int (*__xdm_SecureDisplay)() = NULL; -int (*__xdm_UnsecureDisplay)() = NULL; -int (*__xdm_ClearCloseOnFork)() = NULL; -int (*__xdm_SetupDisplay)() = NULL; -int (*__xdm_LogError)() = NULL; -int (*__xdm_SessionExit)() = NULL; -int (*__xdm_DeleteXloginResources)() = NULL; -int (*__xdm_source)() = NULL; -char **(*__xdm_defaultEnv)() = NULL; -char **(*__xdm_setEnv)() = NULL; -char **(*__xdm_parseArgs)() = NULL; -int (*__xdm_printEnv)() = NULL; -char **(*__xdm_systemEnv)() = NULL; -int (*__xdm_LogOutOfMem)() = NULL; -void (*__xdm_setgrent)() = NULL; -struct group *(*__xdm_getgrent)() = NULL; -void (*__xdm_endgrent)() = NULL; +int (*__xdm_PingServer)(struct display *d, Display *alternateDpy) = NULL; +void (*__xdm_SessionPingFailed)(struct display *d) = NULL; +void (*__xdm_Debug)(char * fmt, ...) = NULL; +void (*__xdm_RegisterCloseOnFork)(int fd) = NULL; +void (*__xdm_SecureDisplay)(struct display *d, Display *dpy) = NULL; +void (*__xdm_UnsecureDisplay)(struct display *d, Display *dpy) = NULL; +void (*__xdm_ClearCloseOnFork)(int fd) = NULL; +void (*__xdm_SetupDisplay)(struct display *d) = NULL; +void (*__xdm_LogError)(char * fmt, ...) = NULL; +void (*__xdm_SessionExit)(struct display *d, int status, int removeAuth) = NULL; +void (*__xdm_DeleteXloginResources)(struct display *d, Display *dpy) = NULL; +int (*__xdm_source)(char **environ, char *file) = NULL; +char **(*__xdm_defaultEnv)(void) = NULL; +char **(*__xdm_setEnv)(char **e, char *name, char *value) = NULL; +char **(*__xdm_putEnv)(const char *string, char **env) = NULL; +char **(*__xdm_parseArgs)(char **argv, char *string) = NULL; +void (*__xdm_printEnv)(char **e) = NULL; +char **(*__xdm_systemEnv)(struct display *d, char *user, char *home) = NULL; +void (*__xdm_LogOutOfMem)(char * fmt, ...) = NULL; +void (*__xdm_setgrent)(void) = NULL; +struct group *(*__xdm_getgrent)(void) = NULL; +void (*__xdm_endgrent)(void) = NULL; #ifdef USESHADOW -struct spwd *(*__xdm_getspnam)() = NULL; -void (*__xdm_endspent)() = NULL; +struct spwd *(*__xdm_getspnam)(GETSPNAM_ARGS) = NULL; +void (*__xdm_endspent)(void) = NULL; +#endif +struct passwd *(*__xdm_getpwnam)(GETPWNAM_ARGS) = NULL; +#ifdef linux +void (*__xdm_endpwent)(void) = NULL; +#endif +char *(*__xdm_crypt)(CRYPT_ARGS) = NULL; +#ifdef USE_PAM +pam_handle_t **(*__xdm_thepamhp)(void) = NULL; #endif -struct passwd *(*__xdm_getpwnam)() = NULL; -char *(*__xdm_crypt)() = NULL; #endif @@ -99,9 +121,9 @@ static XtIntervalId pingTimeout; /*ARGSUSED*/ static void -GreetPingServer (closure, intervalId) - XtPointer closure; - XtIntervalId *intervalId; +GreetPingServer ( + XtPointer closure, + XtIntervalId *intervalId) { struct display *d; @@ -114,10 +136,10 @@ GreetPingServer (closure, intervalId) /*ARGSUSED*/ static void -GreetDone (w, data, status) - Widget w; - LoginData *data; - int status; +GreetDone ( + Widget w, + LoginData *data, + int status) { Debug ("GreetDone: %s, (password is %d long)\n", data->name, strlen (data->passwd)); @@ -125,7 +147,7 @@ GreetDone (w, data, status) case NOTIFY_OK: strcpy (name, data->name); strcpy (password, data->passwd); - bzero (data->passwd, NAME_LEN); + bzero (data->passwd, PASSWORD_LEN); code = 0; done = 1; break; @@ -148,8 +170,7 @@ GreetDone (w, data, status) } static Display * -InitGreet (d) - struct display *d; +InitGreet (struct display *d) { Arg arglist[10]; int i; @@ -157,6 +178,10 @@ InitGreet (d) Screen *scrn; static char *argv[] = { "xlogin", 0 }; Display *dpy; +#ifdef USE_XINERAMA + XineramaScreenInfo *screens; + int s_num; +#endif Debug ("greet %s\n", d->name); argc = 1; @@ -168,15 +193,16 @@ InitGreet (d) if (!dpy) return 0; +#ifdef XKB { int opcode, evbase, errbase, majret, minret; unsigned int value = XkbPCF_GrabsUseXKBStateMask; if (XkbQueryExtension (dpy, &opcode, &evbase, &errbase, &majret, &minret)) { - if (XkbSetPerClientControls (dpy, XkbPCF_GrabsUseXKBStateMask, &value)) + if (!XkbSetPerClientControls (dpy, XkbPCF_GrabsUseXKBStateMask, &value)) LogError ("%s\n", "SetPerClientControls failed"); } } - +#endif RegisterCloseOnFork (ConnectionNumber (dpy)); SecureDisplay (d, dpy); @@ -200,6 +226,21 @@ InitGreet (d) arglist, i); XtRealizeWidget (toplevel); +#ifdef USE_XINERAMA + if ( + XineramaIsActive(dpy) && + (screens = XineramaQueryScreens(dpy, &s_num)) != NULL + ) + { + XWarpPointer(dpy, None, XRootWindowOfScreen (scrn), + 0, 0, 0, 0, + screens[0].x_org + screens[0].width / 2, + screens[0].y_org + screens[0].height / 2); + + XFree(screens); + } + else +#endif XWarpPointer(dpy, None, XRootWindowOfScreen (scrn), 0, 0, 0, 0, XWidthOfScreen(scrn) / 2, @@ -213,9 +254,8 @@ InitGreet (d) return dpy; } -static -CloseGreet (d) - struct display *d; +static void +CloseGreet (struct display *d) { Boolean allow; Arg arglist[1]; @@ -241,12 +281,10 @@ CloseGreet (d) } static int -Greet (d, greet) - struct display *d; - struct greet_info *greet; +Greet (struct display *d, struct greet_info *greet) { XEvent event; - Arg arglist[1]; + Arg arglist[3]; XtSetArg (arglist[0], XtNallowAccess, False); XtSetValues (login, arglist, 1); @@ -254,8 +292,15 @@ Greet (d, greet) Debug ("dispatching %s\n", d->name); done = 0; while (!done) { - XtAppNextEvent (context, &event); + XtAppNextEvent (context, &event); + switch (event.type) { + case MappingNotify: + XRefreshKeyboardMapping(&event.xmapping); + break; + default: XtDispatchEvent (&event); + break; + } } XFlush (XtDisplay (toplevel)); Debug ("Done dispatch %s\n", d->name); @@ -264,7 +309,9 @@ Greet (d, greet) greet->name = name; greet->password = password; XtSetArg (arglist[0], XtNsessionArgument, (char *) &(greet->string)); - XtGetValues (login, arglist, 1); + XtSetArg (arglist[1], XtNallowNullPasswd, (char *) &(greet->allow_null_passwd)); + XtSetArg (arglist[2], XtNallowRootLogin, (char *) &(greet->allow_root_login)); + XtGetValues (login, arglist, 3); Debug ("sessionArgument: %s\n", greet->string ? greet->string : "<NULL>"); } return code; @@ -272,22 +319,27 @@ Greet (d, greet) static void -FailedLogin (d, greet) - struct display *d; - struct greet_info *greet; +FailedLogin (struct display *d, struct greet_info *greet) { +#ifdef __OpenBSD__ + syslog(LOG_NOTICE, "LOGIN FAILURE ON %s", + d->name); + syslog(LOG_AUTHPRIV|LOG_NOTICE, + "LOGIN FAILURE ON %s, %s", + d->name, greet->name); +#endif DrawFail (login); bzero (greet->name, strlen(greet->name)); bzero (greet->password, strlen(greet->password)); } -greet_user_rtn GreetUser(d, dpy, verify, greet, dlfuncs) - struct display *d; - Display ** dpy; - struct verify_info *verify; - struct greet_info *greet; - struct dlfuncs *dlfuncs; +greet_user_rtn GreetUser( + struct display *d, + Display ** dpy, + struct verify_info *verify, + struct greet_info *greet, + struct dlfuncs *dlfuncs) { int i; @@ -309,6 +361,7 @@ greet_user_rtn GreetUser(d, dpy, verify, greet, dlfuncs) __xdm_source = dlfuncs->_source; __xdm_defaultEnv = dlfuncs->_defaultEnv; __xdm_setEnv = dlfuncs->_setEnv; + __xdm_putEnv = dlfuncs->_putEnv; __xdm_parseArgs = dlfuncs->_parseArgs; __xdm_printEnv = dlfuncs->_printEnv; __xdm_systemEnv = dlfuncs->_systemEnv; @@ -321,7 +374,13 @@ greet_user_rtn GreetUser(d, dpy, verify, greet, dlfuncs) __xdm_endspent = dlfuncs->_endspent; #endif __xdm_getpwnam = dlfuncs->_getpwnam; +#ifdef linux + __xdm_endpwent = dlfuncs->_endpwent; +#endif __xdm_crypt = dlfuncs->_crypt; +#ifdef USE_PAM + __xdm_thepamhp = dlfuncs->_thepamhp; +#endif #endif *dpy = InitGreet (d); @@ -335,6 +394,9 @@ greet_user_rtn GreetUser(d, dpy, verify, greet, dlfuncs) LogError ("Cannot reopen display %s for greet window\n", d->name); exit (RESERVER_DISPLAY); } +#ifdef __OpenBSD__ + openlog("xdm", LOG_ODELAY, LOG_AUTH); +#endif for (;;) { /* * Greet user, requesting name/password diff --git a/greeter/verify.c b/greeter/verify.c index 52b8138..182fef4 100644 --- a/greeter/verify.c +++ b/greeter/verify.c @@ -26,6 +26,7 @@ other dealings in this Software without prior written authorization from The Open Group. */ +/* $XFree86: xc/programs/xdm/greeter/verify.c,v 3.24 2002/11/26 01:16:09 dawes Exp $ */ /* * xdm - display manager daemon @@ -36,20 +37,24 @@ from The Open Group. * typical unix verification routine. */ -# include "dm.h" -# include <pwd.h> -#ifdef USESHADOW -# include <shadow.h> -# include <errno.h> -#ifdef X_NOT_STDC_ENV -extern int errno; -#endif +#include "dm.h" +#include "dm_error.h" + +#include <pwd.h> +#ifdef USE_PAM +# include <security/pam_appl.h> +# include <stdlib.h> +#else +# ifdef USESHADOW +# include <shadow.h> +# include <errno.h> +# endif #endif # include "greet.h" -#ifdef X_NOT_STDC_ENV -char *getenv(); +#ifdef QNX4 +extern char *crypt(const char *, const char *); #endif static char *envvars[] = { @@ -71,17 +76,19 @@ static char *envvars[] = { NULL }; +#ifdef KERBEROS +#include <sys/param.h> +#include <kerberosIV/krb.h> +static char krbtkfile[MAXPATHLEN]; +#endif + static char ** -userEnv (d, useSystemPath, user, home, shell) -struct display *d; -int useSystemPath; -char *user, *home, *shell; +userEnv (struct display *d, int useSystemPath, char *user, char *home, char *shell) { char **env; char **envvar; char *str; - extern char **defaultEnv (), **setEnv (); - + env = defaultEnv (); env = setEnv (env, "DISPLAY", d->name); env = setEnv (env, "HOME", home); @@ -89,6 +96,10 @@ char *user, *home, *shell; env = setEnv (env, "USER", user); /* BSD */ env = setEnv (env, "PATH", useSystemPath ? d->systemPath : d->userPath); env = setEnv (env, "SHELL", shell); +#ifdef KERBEROS + if (krbtkfile[0] != '\0') + env = setEnv (env, "KRBTKFILE", krbtkfile); +#endif for (envvar = envvars; *envvar; envvar++) { str = getenv(*envvar); @@ -98,33 +109,260 @@ char *user, *home, *shell; return env; } +#ifdef USE_PAM +static char *PAM_password; +static int pam_error; + +static int PAM_conv (int num_msg, +#ifdef sun + struct pam_message **msg, +#else + const struct pam_message **msg, +#endif + struct pam_response **resp, + void *appdata_ptr) { + int count = 0, replies = 0; + struct pam_response *reply = NULL; + +#define PAM_RESPONSE_SIZE sizeof(struct pam_response) + size_t size = PAM_RESPONSE_SIZE; + +#define COPY_STRING(s) (s) ? strdup(s) : (char*)NULL + + for (count = 0; count < num_msg; count++) { + switch (msg[count]->msg_style) { + case PAM_PROMPT_ECHO_ON: + /* user name given to PAM already */ + return PAM_CONV_ERR; + case PAM_PROMPT_ECHO_OFF: + /* wants password */ + if (reply) { + reply = realloc(reply, size); + bzero(reply + size - PAM_RESPONSE_SIZE, PAM_RESPONSE_SIZE); + } else { + reply = (struct pam_response*)malloc(size); + bzero(reply, size); + } + + if (!reply) + return PAM_CONV_ERR; + + size += PAM_RESPONSE_SIZE; + + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies].resp = COPY_STRING(PAM_password); + /* PAM frees resp */ + break; + case PAM_TEXT_INFO: + /* ignore the informational mesage */ + break; + default: + /* unknown or PAM_ERROR_MSG */ + if (reply) free (reply); + return PAM_CONV_ERR; + } + } + +#undef COPY_STRING + if (reply) *resp = reply; + return PAM_SUCCESS; +} + +static struct pam_conv PAM_conversation = { + PAM_conv, + NULL +}; +#endif /* USE_PAM */ + +#ifdef USE_BSDAUTH int -Verify (d, greet, verify) -struct display *d; -struct greet_info *greet; -struct verify_info *verify; +Verify (struct display *d, struct greet_info *greet, struct verify_info *verify) { struct passwd *p; + login_cap_t *lc; + auth_session_t *as; + char *style, *shell, *home, *s, **argv; + char path[MAXPATHLEN]; + int authok; + + /* User may have specified an authentication style. */ + if ((style = strchr(greet->name, ':')) != NULL) + *style++ = '\0'; + + Debug ("Verify %s, style %s ...\n", greet->name, + style ? style : "default"); + + p = getpwnam (greet->name); + endpwent(); + + if (!p || strlen (greet->name) == 0) { + Debug("getpwnam() failed.\n"); + bzero(greet->password, strlen(greet->password)); + return 0; + } + + if ((lc = login_getclass(p->pw_class)) == NULL) { + Debug("login_getclass() failed.\n"); + bzero(greet->password, strlen(greet->password)); + return 0; + } + if ((style = login_getstyle(lc, style, "xdm")) == NULL) { + Debug("login_getstyle() failed.\n"); + bzero(greet->password, strlen(greet->password)); + return 0; + } + if ((as = auth_open()) == NULL) { + Debug("auth_open() failed.\n"); + login_close(lc); + bzero(greet->password, strlen(greet->password)); + return 0; + } + if (auth_setoption(as, "login", "yes") == -1) { + Debug("auth_setoption() failed.\n"); + login_close(lc); + bzero(greet->password, strlen(greet->password)); + return 0; + } + + /* Set up state for no challenge, just check a response. */ + auth_setstate(as, 0); + auth_setdata(as, "", 1); + auth_setdata(as, greet->password, strlen(greet->password) + 1); + + /* Build path of the auth script and call it */ + snprintf(path, sizeof(path), _PATH_AUTHPROG "%s", style); + auth_call(as, path, style, "-s", "response", greet->name, + (void *)NULL); + authok = auth_getstate(as); + + if ((authok & AUTH_ALLOW) == 0) { + Debug("password verify failed\n"); + bzero(greet->password, strlen(greet->password)); + auth_close(as); + login_close(lc); + return 0; + } + /* Run the approval script */ + if (!auth_approval(as, lc, greet->name, "auth-xdm")) { + Debug("login not approved\n"); + bzero(greet->password, strlen(greet->password)); + auth_close(as); + login_close(lc); + return 0; + } + auth_close(as); + login_close(lc); + /* Check empty passwords against allowNullPasswd */ + if (!greet->allow_null_passwd && strlen(greet->password) == 0) { + Debug("empty password not allowed\n"); + return 0; + } + /* Only accept root logins if allowRootLogin resource is set */ + if (p->pw_uid == 0 && !greet->allow_root_login) { + Debug("root logins not allowed\n"); + bzero(greet->password, strlen(greet->password)); + return 0; + } + + /* + * Shell must be in /etc/shells + */ + for (;;) { + s = getusershell(); + if (s == NULL) { + /* did not found the shell in /etc/shells + -> failure */ + Debug("shell not in /etc/shells\n"); + bzero(greet->password, strlen(greet->password)); + endusershell(); + return 0; + } + if (strcmp(s, p->pw_shell) == 0) { + /* found the shell in /etc/shells */ + endusershell(); + break; + } + } +#else /* !USE_BSDAUTH */ +int +Verify (struct display *d, struct greet_info *greet, struct verify_info *verify) +{ + struct passwd *p; +#ifdef USE_PAM + pam_handle_t **pamhp = thepamhp(); +#else #ifdef USESHADOW struct spwd *sp; #endif - char *user_pass; -#if !defined(SVR4) || !defined(GREET_LIB) /* shared lib decls handle this */ - char *crypt (); - char **systemEnv (), **parseArgs (); + char *user_pass = NULL; +#endif +#ifdef __OpenBSD__ + char *s; + struct timeval tp; #endif char *shell, *home; char **argv; Debug ("Verify %s ...\n", greet->name); +#ifndef USE_PAM p = getpwnam (greet->name); + endpwent(); + if (!p || strlen (greet->name) == 0) { Debug ("getpwnam() failed.\n"); bzero(greet->password, strlen(greet->password)); return 0; } else { +#ifdef linux + if (!strcmp(p->pw_passwd, "!") || !strcmp(p->pw_passwd, "*")) { + Debug ("The account is locked, no login allowed.\n"); + bzero(greet->password, strlen(greet->password)); + return 0; + } +#endif user_pass = p->pw_passwd; } +#endif +#ifdef KERBEROS + if(strcmp(greet->name, "root") != 0){ + char name[ANAME_SZ]; + char realm[REALM_SZ]; + char *q; + int ret; + + if(krb_get_lrealm(realm, 1)){ + Debug ("Can't get Kerberos realm.\n"); + } else { + + sprintf(krbtkfile, "%s.%s", TKT_ROOT, d->name); + krb_set_tkt_string(krbtkfile); + unlink(krbtkfile); + + ret = krb_verify_user(greet->name, "", realm, + greet->password, 1, "rcmd"); + + if(ret == KSUCCESS){ + chown(krbtkfile, p->pw_uid, p->pw_gid); + Debug("kerberos verify succeeded\n"); + if (k_hasafs()) { + if (k_setpag() == -1) + LogError ("setpag() failed for %s\n", + greet->name); + + if((ret = k_afsklog(NULL, NULL)) != KSUCCESS) + LogError("Warning %s\n", + krb_get_err_text(ret)); + } + goto done; + } else if(ret != KDC_PR_UNKNOWN && ret != SKDC_CANT){ + /* failure */ + Debug("kerberos verify failure %d\n", ret); + krbtkfile[0] = '\0'; + } + } + } +#endif +#ifndef USE_PAM #ifdef USESHADOW errno = 0; sp = getspnam(greet->name); @@ -133,7 +371,9 @@ struct verify_info *verify; } else { user_pass = sp->sp_pwdp; } +#ifndef QNX4 endspent(); +#endif /* QNX4 doesn't need endspent() to end shadow passwd ops */ #endif #if defined(ultrix) || defined(__ultrix__) if (authenticate_user(p, greet->password, NULL) < 0) @@ -141,12 +381,103 @@ struct verify_info *verify; if (strcmp (crypt (greet->password, user_pass), user_pass)) #endif { - Debug ("password verify failed\n"); + if(!greet->allow_null_passwd || strlen(p->pw_passwd) > 0) { + Debug ("password verify failed\n"); + bzero(greet->password, strlen(greet->password)); + return 0; + } /* else: null passwd okay */ + } +#ifdef KERBEROS +done: +#endif +#ifdef __OpenBSD__ + /* + * Only accept root logins if allowRootLogin resource is set + */ + if ((p->pw_uid == 0) && !greet->allow_root_login) { + Debug("root logins not allowed\n"); bzero(greet->password, strlen(greet->password)); return 0; } - Debug ("verify succeeded\n"); + /* + * Shell must be in /etc/shells + */ + for (;;) { + s = getusershell(); + if (s == NULL) { + /* did not found the shell in /etc/shells + -> failure */ + Debug("shell not in /etc/shells\n"); + bzero(greet->password, strlen(greet->password)); + endusershell(); + return 0; + } + if (strcmp(s, p->pw_shell) == 0) { + /* found the shell in /etc/shells */ + endusershell(); + break; + } + } + /* + * Test for expired password + */ + if (p->pw_change || p->pw_expire) + (void)gettimeofday(&tp, (struct timezone *)NULL); + if (p->pw_change) { + if (tp.tv_sec >= p->pw_change) { + Debug("Password has expired.\n"); + bzero(greet->password, strlen(greet->password)); + return 0; + } + } + if (p->pw_expire) { + if (tp.tv_sec >= p->pw_expire) { + Debug("account has expired.\n"); + bzero(greet->password, strlen(greet->password)); + return 0; + } + } +#endif /* __OpenBSD__ */ bzero(user_pass, strlen(user_pass)); /* in case shadow password */ + +#else /* USE_PAM */ +#define PAM_BAIL \ + if (pam_error != PAM_SUCCESS) goto pam_failed; + + PAM_password = greet->password; + pam_error = pam_start("xdm", greet->name, &PAM_conversation, pamhp); + PAM_BAIL; + pam_error = pam_set_item(*pamhp, PAM_TTY, d->name); + PAM_BAIL; + pam_error = pam_set_item(*pamhp, PAM_RHOST, ""); + PAM_BAIL; + pam_error = pam_authenticate(*pamhp, 0); + PAM_BAIL; + pam_error = pam_acct_mgmt(*pamhp, 0); + /* really should do password changing, but it doesn't fit well */ + PAM_BAIL; + pam_error = pam_setcred(*pamhp, 0); + PAM_BAIL; + p = getpwnam (greet->name); + endpwent(); + + if (!p || strlen (greet->name) == 0) { + Debug ("getpwnam() failed.\n"); + bzero(greet->password, strlen(greet->password)); + return 0; + } + + if (pam_error != PAM_SUCCESS) { + pam_failed: + pam_end(*pamhp, PAM_SUCCESS); + *pamhp = NULL; + return 0; + } +#undef PAM_BAIL +#endif /* USE_PAM */ +#endif /* USE_BSDAUTH */ + + Debug ("verify succeeded\n"); /* The password is passed to StartClient() for use by user-based authorization schemes. It is zeroed there. */ verify->uid = p->pw_uid; |