123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /* (c) Copyright 1997 The Open Group */
- /* *
- * (c) Copyright 1993, 1994 Hewlett-Packard Company *
- * (c) Copyright 1993, 1994 International Business Machines Corp. *
- * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
- * (c) Copyright 1993, 1994 Novell, Inc. *
- */
- /*
- * Xdm - display manager daemon
- *
- * $TOG: session.c /main/21 1998/11/02 14:32:42 mgreess $
- *
- * Copyright 1988 Massachusetts Institute of Technology
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of M.I.T. not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. M.I.T. makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * Author: Keith Packard, MIT X Consortium
- */
- /*
- * session.c
- */
- #ifdef _AIX
- #ifdef _POWER
- #include <stdio.h>
- #include <errno.h>
- #include <sys/file.h>
- #endif /* _POWER */
- # include <usersec.h>
- #endif /* _AIX */
- # include "dm.h"
- # include "vgmsg.h"
- # include <signal.h>
- # include <X11/Xatom.h>
- # include <setjmp.h>
- #if defined(__FreeBSD__) && OSMAJORVERSION > 8
- # include <utmpx.h>
- #else
- # include <utmp.h>
- #endif
- #include <unistd.h>
- #include <pwd.h>
- #include <dirent.h>
- #include <limits.h>
- #ifdef SIA
- #include <sia.h>
- #include <siad.h>
- #include <X11/Intrinsic.h>
- #endif
- # include <X11/Xresource.h>
- # include "vgproto.h"
- # include "sysauth.h"
- #ifdef sun
- # include "solaris.h"
- #endif
- #ifdef BLS
- # include <sys/security.h>
- # include <prot.h>
- #endif
- #ifdef __KERBEROS
- # include <krb.h>
- #endif /* __KERBEROS */
- #ifdef __PASSWD_ETC
- #include "rgy_base.h"
- #endif
- #ifdef SIA
- static SIAENTITY *siaHandle = NULL;
- static Boolean dt_in_sia_ses_authent = False;
- static struct sia_greeter_info {
- struct display *d;
- struct greet_info *greet;
- struct verify_info *verify;
- struct greet_state *state;
- int status;
- } siaGreeterInfo;
- static int SiaManageGreeter(
- int timeout,
- int rendition,
- unsigned char *title,
- int num_prompts,
- prompt_t *prompt);
- static CopySiaInfo(SIAENTITY *siaHandle, struct greet_info *greet);
- static void KillGreeter( void );
- static int sia_greeter_pid;
- static int sia_exit_proc_reg = FALSE;
- #endif /* SIA */
- #define GREET_STATE_LOGIN 0
- #define GREET_STATE_AUTHENTICATE 1
- #define GREET_STATE_EXIT 2
- #define GREET_STATE_EXPASSWORD 3
- #define GREET_STATE_ERRORMESSAGE 4
- #define GREET_STATE_LANG 5
- #define GREET_STATE_BAD_HOSTNAME 6
- #define GREET_STATE_ENTER 7
- #define GREET_STATE_TERMINATEGREET 8
- #define GREET_STATE_USERNAME 9
- #define GREET_STATE_CHALLENGE 10
- #define GREET_STATE_FORM 11
- #ifndef DEF_SESSION
- #define DEF_SESSION CDE_INSTALLATION_TOP "/bin/Xsession"
- #endif
- #define DOT "."
- #define DOTDOT ".."
- struct greet_state {
- int id; /* state */
- int waitForResponse; /* TRUE=wait for response from dtgreet */
- RequestHeader *request; /* request buffer */
- ResponseHeader *response; /* response buffer */
- int authenticated; /* TRUE=user is authenticated */
- int vf; /* last return code from Authenticate() */
- int loginReset; /* reset flag for LOGIN state */
- char *msg; /* message for VF_MESSAGE */
- };
- char *globalDisplayName;
- /***************************************************************************
- *
- * Local procedure declarations
- *
- ***************************************************************************/
- static int AbortClient( int pid) ;
- static void DeleteXloginResources( struct display *d, Display *dpy) ;
- int LoadXloginResources( struct display *d) ;
- static int ErrorHandler( Display *dpy, XErrorEvent *event) ;
- static int IOErrorHandler( Display *dpy) ;
- static int ManageGreeter( struct display *d, struct greet_info *greet,
- struct verify_info *verify, struct greet_state *state) ;
- static void RunGreeter( struct display *d, struct greet_info *greet,
- struct verify_info *verify) ;
- static void SessionExit( struct display *d, int status) ;
- static void SessionPingFailed( struct display *d) ;
- static int StartClient(struct verify_info *verify, struct display *d,
- int *pidp) ;
- static SIGVAL catchAlrm( int arg ) ;
- static SIGVAL catchHUP( int arg ) ;
- static SIGVAL catchTerm( int arg ) ;
- static SIGVAL waitAbort( int arg ) ;
- static void SetupDisplay(struct display *d);
- static void TellGreeter(RequestHeader *phdr);
- static int AskGreeter(RequestHeader *preqhdr, char *b, int blen);
- #if defined (DEBUG)
- static void PrintResponse(ResponseHeader *phdr, int count);
- #endif /* DEBUG */
- #if defined (_AIX) && defined (_POWER)
- static void release_aix_lic(void);
- #endif
- #if defined (_AIX) && !defined (_POWER)
- static int session_execve(char *path, char *argv[], char *envp[]);
- #else
- #define session_execve(A,B,C) execve(A,B,C)
- #endif
- # ifdef __KERBEROS
- static void SetTicketFileName(uid_t uid);
- # endif /* __KERBEROS */
- static void LoadAltDtsResources( struct display *d);
- char * _ExpandLang(char *string, char *lang);
- /***************************************************************************
- *
- * Global variables
- *
- ***************************************************************************/
- static int clientPid;
- static struct greet_info greet;
- static struct verify_info verify;
- static char *defaultLanguage = NULL;
- static jmp_buf abortSession;
- #ifdef BLS
- static char *sensitivityLevel;
- #endif
- #ifdef __KERBEROS
- static char krb_ticket_string[MAXPATHLEN];
- #endif /* __KERBEROS */
- XrmDatabase XresourceDB;
- XrmDatabase XDB;
- static SIGVAL
- catchTerm( int arg )
- {
- longjmp (abortSession, 1);
- }
- static jmp_buf pingTime;
- static SIGVAL
- catchAlrm( int arg )
- {
- longjmp (pingTime, 1);
- }
- #if defined(__STDC__)
- static int
- FileNameCompare (const char *a, const char *b)
- #else
- static int
- FileNameCompare (char *a, char *b)
- #endif
- {
- return strcoll (*(char **)a, *(char **)b);
- }
- static void
- SessionPingFailed( struct display *d )
- {
- if (clientPid > 1)
- {
- AbortClient (clientPid);
- source (&verify, d->reset);
- #if defined (PAM) || defined(SUNAUTH)
- {
- char* user = getEnv (verify.userEnviron, "USER");
- char* ttyLine = d->gettyLine;
-
- #ifdef DEF_NETWORK_DEV
- /*
- * If location is not local (remote XDMCP dtlogin) and
- * remote accouting is enabled (networkDev start with /dev/...)
- * Set tty line name to match network device for accouting.
- * Unless the resource was specifically set, default is value
- * of DEF_NETWORK_DEV define (/dev/dtremote)
- */
-
- if ( d->displayType.location != Local &&
- networkDev && !strncmp(networkDev,"/dev/",5)) {
- ttyLine = networkDev+5;
- }
- #endif
- # ifdef PAM
- PamAccounting( verify.argv[0], d->name, d->utmpId, user,
- ttyLine, clientPid, ACCOUNTING, NULL);
- # else
- solaris_accounting( verify.argv[0], d->name, d->utmpId, user,
- ttyLine, clientPid, ACCOUNTING, NULL);
- # endif
- # ifdef sun
- solaris_resetdevperm(ttyLine);
- # endif
- }
- #endif
- }
- SessionExit (d, RESERVER_DISPLAY);
- }
- /*
- * We need our own error handlers because we can't be sure what exit code Xlib
- * will use, and our Xlib does exit(1) which matches REMANAGE_DISPLAY, which
- * can cause a race condition leaving the display wedged. We need to use
- * RESERVER_DISPLAY for IO errors, to ensure that the manager waits for the
- * server to terminate. For other X errors, we should give up.
- */
- static int
- IOErrorHandler( Display *dpy )
- {
- const char *s = strerror(errno);
- LogError(ReadCatalog(
- MC_LOG_SET,MC_LOG_FATAL_IO,MC_DEF_LOG_FATAL_IO),
- errno,s);
- exit(RESERVER_DISPLAY);
- return 0;
- }
- static int
- ErrorHandler( Display *dpy, XErrorEvent *event )
- {
- LogError(ReadCatalog(MC_LOG_SET,MC_LOG_X_ERR,MC_DEF_LOG_X_ERR));
- if (XmuPrintDefaultErrorMessage (dpy, event, stderr) == 0) return 0;
- exit(UNMANAGE_DISPLAY);
- }
- Display *dpy;
- void
- ManageSession( struct display *d )
- {
- int pid;
- Window root;
- /* Display *dpy; */
- #ifdef BYPASSLOGIN
- char *BypassUsername;
- char *BypassLogin();
- #endif /* BYPASSLOGIN */
-
- Debug ("ManageSession():\n");
- /***********************************/
- /** remember the default language **/
- /***********************************/
- if (defaultLanguage == NULL) {
- if ( (d->language != NULL) && (strlen(d->language) > 0) ) {
- defaultLanguage = strdup(d->language);
- } else {
- defaultLanguage = "C";
- }
- }
- #ifdef BYPASSLOGIN
- d->bypassLogin = 0;
- if ((BypassUsername = BypassLogin(d->name)) != NULL) {
- d->bypassLogin = 1;
- Debug("Login bypassed, running as %s\n",BypassUsername);
- greet.name = BypassUsername;
- if (!Verify (d, &greet, &verify)) {
- Debug ("Login bypass verify failed!\n");
- SessionExit (d, GREETLESS_FAILED);
- }
- Debug("Login bypass verify succeded!\n");
- } else
- #endif /* BYPASSLOGIN */
- {
- int i;
- (void)XSetIOErrorHandler(IOErrorHandler);
- (void)XSetErrorHandler(ErrorHandler);
- SetTitle(d->name, (char *) 0);
- /*
- * set root background to black...
- */
- dpy = XOpenDisplay(d->name);
- for (i = ScreenCount(dpy) - 1; i >= 0; i--)
- {
- Window tmproot = RootWindow(dpy, i);
- if (i == DefaultScreen(dpy))
- root = tmproot;
-
- XSetWindowBackground(dpy, tmproot, BlackPixel(dpy, i));
- XClearWindow(dpy, tmproot);
- }
- XFlush(dpy);
- /*
- ** Step 5:
- ** Invoke Greet program, wait for completion.
- ** If this routine returns, the user will have been
- ** verified, otherwise the routine will exit inter-
- ** nally with an appropriate exit code for the master
- ** Dtlogin process.
- */
-
- greet.name = greet.string = NULL;
- while (greet.name == NULL) {
- SetHourGlassCursor(dpy, root);
- LoadXloginResources (d);
- SetupDisplay(d);
- ApplyFontPathMods(d, dpy);
- (void)XSetErrorHandler(ErrorHandler);
- RunGreeter(d, &greet, &verify);
- DeleteXloginResources (d, dpy);
- }
- XSetInputFocus(dpy, root, RevertToNone, CurrentTime);
- XCloseDisplay(dpy);
- }
- #ifdef __KERBEROS
- /*
- * Generate Kerberos ticket file name. Put in system and user
- * environments...
- */
- if ( IsVerifyName(VN_KRB)) {
- SetTicketFileName(verify.uid);
- krb_set_tkt_string(krb_ticket_string);
- verify.systemEnviron = setEnv (verify.systemEnviron,
- "KRBTKFILE",
- krb_ticket_string);
- verify.userEnviron = setEnv (verify.userEnviron,
- "KRBTKFILE",
- krb_ticket_string);
- }
- #endif /* __KERBEROS */
- /* set LOCATION env var */
- if(d->displayType.location == Local) {
- verify.systemEnviron = setEnv (verify.systemEnviron,
- LOCATION,
- "local");
- /* ITE is needed only for Local displays */
- /* set ITE env var */
- if(d->gettyLine)
- verify.systemEnviron = setEnv (verify.systemEnviron,
- "ITE",
- d->gettyLine);
- }
- else
- verify.systemEnviron = setEnv (verify.systemEnviron,
- LOCATION,
- "remote");
- {
- struct passwd *pwd;
- char gid[25];
- sprintf(gid,"%ld",(long)getgid());
- /* set user group id (USER_GID) env var */
- verify.systemEnviron = setEnv (verify.systemEnviron,
- "USER_GID",
- gid);
- /* set root group id (ROOT_GID) env var */
- pwd = getpwnam("root");
- if(pwd) {
- sprintf(gid,"%ld",(long)pwd->pw_gid);
- verify.systemEnviron = setEnv (verify.systemEnviron,
- "ROOT_GID",
- gid);
- }
- }
- /*
- * Run system-wide initialization file
- */
- if (source (&verify, d->startup) != 0)
- {
- Debug ("Startup program %s exited with non-zero status\n",
- d->startup);
- SessionExit (d, OBEYSESS_DISPLAY);
- }
- #ifdef sun
- if ( solaris_setdevperm(d->gettyLine, verify.uid, verify.gid) == 0 ) {
- SessionExit (d, OBEYSESS_DISPLAY);
- }
- #endif
- clientPid = 0;
- if (!setjmp (abortSession)) {
- signal (SIGTERM, catchTerm);
- /*
- * Start the clients, changing uid/groups
- * setting up environment and running the session
- */
- if (StartClient (&verify, d, &clientPid)) {
- Debug ("Client started\n");
- /*
- * We've changed dtlogin to pass HUP's down to the children
- * so ignore any HUP's once the client has started.
- */
- signal(SIGHUP, SIG_IGN);
- /*
- * Wait for session to end,
- */
- for (;;) {
- if (d->pingInterval)
- {
- if (!setjmp (pingTime))
- {
- signal (SIGALRM, catchAlrm);
- alarm (d->pingInterval * 60);
- pid = wait ((waitType *) 0);
- alarm (0);
- }
- else
- {
- alarm (0);
- if (!PingServer (d, (Display *) NULL))
- SessionPingFailed (d);
- }
- }
- else
- {
- pid = wait ((waitType *) 0);
- }
- if (pid == clientPid)
- break;
- }
- /*
- * We've changed dtlogin to pass HUP's down to the children
- * so ignore any HUP's once the client has started.
- */
- signal(SIGHUP, SIG_DFL);
- } else {
- LogError(ReadCatalog(
- MC_LOG_SET,MC_LOG_FAIL_START,MC_DEF_LOG_FAIL_START));
- }
- } else {
- /*
- * when terminating the session, nuke
- * the child and then run the reset script
- */
- AbortClient (clientPid);
- }
- /*
- * on foreign displays without XDMCP, send a SIGTERM to the process
- * group of the session manager. This augments the "resetServer()"
- * routine and helps get all clients killed. It is possible for a client
- * to have a connection to the server, but not have a window.
- */
- if (d->displayType.location == Foreign &&
- d->displayType.origin != FromXDMCP )
- AbortClient(clientPid);
- #ifdef __KERBEROS
- /*
- * remove ticket file...
- */
- if ( IsVerifyName(VN_KRB) ) {
- dest_tkt();
- }
- #endif /* __KERBEROS */
-
- /*
- * run system-wide reset file
- */
- Debug ("Source reset program %s\n", d->reset);
- source (&verify, d->reset);
- #if defined(PAM) || defined(SUNAUTH)
- {
- char* user = getEnv (verify.userEnviron, "USER");
- char* ttyLine = d->gettyLine;
-
- # ifdef DEF_NETWORK_DEV
- /*
- * If location is not local (remote XDMCP dtlogin) and
- * remote accouting is enabled (networkDev start with /dev/...)
- * Set tty line name to match network device for accouting.
- * Unless the resource was specifically set, default is value
- * of DEF_NETWORK_DEV define (/dev/dtremote)
- */
-
- if ( d->displayType.location != Local &&
- networkDev && !strncmp(networkDev,"/dev/",5)) {
- ttyLine = networkDev+5;
- }
- # endif
- # ifdef PAM
- PamAccounting( verify.argv[0], d->name, d->utmpId, user,
- ttyLine, clientPid, ACCOUNTING, NULL);
- # else
- solaris_accounting( verify.argv[0], d->name, d->utmpId, user,
- ttyLine, clientPid, ACCOUNTING, NULL);
- # endif
- # ifdef sun
- solaris_resetdevperm(ttyLine);
- # endif
- }
- #endif
- SessionExit (d, OBEYSESS_DISPLAY);
- }
- int
- LoadXloginResources( struct display *d )
- {
- char cmd[1024];
- char *authority="";
- char *auth_key="";
- char *resources = NULL;
- char *p;
- char tmpname[32];
- if (d->resources && d->resources[0]) {
- resources = _ExpandLang(d->resources, d->language);
- if (access (resources, R_OK) != 0) {
- /** fallback to the C locale for resources **/
- Debug("LoadXloginResources - cant access %s\n", resources);
- Debug("\t %s. Falling back to C.\n", strerror(errno));
- free(resources);
- resources = _ExpandLang(d->resources, "C");
- if (access (resources, R_OK) != 0) {
- /** can't find a resource file, so bail **/
- Debug("LoadXloginResources - cant access %s.\n", resources);
- Debug("\t %s. Unable to find resource file.\n",
- strerror(errno));
- free(resources);
- return(-1);
- }
- }
- if (d->authFile && strlen(d->authFile) > 0 ) {
- authority = d->authFile;
- auth_key = "XAUTHORITY=";
- }
- Debug("LoadXloginResources - loading resource db from %s\n", resources);
- if((XresourceDB = XrmGetFileDatabase(resources)) == NULL)
- Debug("LoadXloginResources - Loading resource db from %s failed\n",
- resources);
- LoadAltDtsResources(d);
- strcpy(tmpname,"/var/dt/dtlogin_XXXXXX");
- (void) mktemp(tmpname);
- XrmPutFileDatabase(XresourceDB, tmpname);
- sprintf (cmd, "%s%s %s -display %s -load %s",
- auth_key, authority, d->xrdb, d->name, tmpname);
- Debug ("Loading resource file: %s\n", cmd);
- if(-1 == system (cmd)) {
- Debug ("system() failed on cmd '%s'\n", cmd);
- return -1;
- }
- if (debugLevel <= 10)
- if (unlink (tmpname) == -1)
- Debug ("unlink() on %s failed\n", tmpname);
- }
- if (resources) free (resources);
- return (0);
- }
- /***************************************************************************
- *
- * LoadAltDtsResources
- *
- *
- * set up alternate desktop resources..
- *
- ***************************************************************************/
-
- static void
- LoadAltDtsResources(struct display *d)
- {
- DIR *dirp;
- struct dirent *dp;
- char dirname[2][MAXPATHLEN];
- char res_file[MAXPATHLEN];
- char *rmtype; /* for XrmGetResource() */
- XrmValue rmvalue; /* for XrmGetResource() */
- char buf[MAXPATHLEN];
- char tempbuf[MAXPATHLEN];
- XrmDatabase defDb;
- XrmDatabase userDb;
- char altdtres[MAXPATHLEN];
- char Altdtres[MAXPATHLEN];
- int i = 0;
- int j = 0;
- char *resources = NULL;
- int file_count = 0;
- int num_allocated = 0;
- char **file_list = NULL;
- int list_incr = 10;
- if ( XrmGetResource(XresourceDB,
- "Dtlogin*altDts", "Dtlogin*AltDts",
- &rmtype, &rmvalue ) ) {
- snprintf(tempbuf, sizeof(tempbuf), "%s", rmvalue.addr);
- i = atoi(tempbuf);
- }
- strcpy(dirname[0],CDE_INSTALLATION_TOP "/config/%L/Xresources.d/");
- strcpy(dirname[1],CDE_CONFIGURATION_TOP "/config/%L/Xresources.d/");
- for(j = 0; j < 2 ; ++j)
- {
- resources = _ExpandLang(dirname[j], d->language);
- if (access (resources, R_OK) != 0)
- {
- Debug("LoadAltDtsResources- cant access %s.\n", resources);
- Debug("\t %s. Falling back to C.\n", strerror(errno));
- free (resources);
- resources = NULL;
- resources = _ExpandLang(dirname[j], "C");
- if (access (resources, R_OK) != 0)
- {
- Debug("LoadAltDtsResources- cant access %s.\n", resources);
- Debug("\t %s.\n", strerror(errno));
- }
- else
- snprintf(dirname[j], sizeof(dirname[j]), "%s", resources);
- }
- else {
- snprintf(dirname[j], sizeof(dirname[j]), "%s", resources);
- Debug("LoadAltDtsResources- found resource dir %s\n", dirname[j]);
- }
- free (resources);
- resources = NULL;
- }
- /*
- * Create a list of the alt DT files
- *
- * NOTE - an assumption made here is that files in /etc/dt
- * should take precedence over files in /usr/dt. This precedence
- * is maintained during the sort becase /etc/dt will come before
- * /usr/dt
- */
- for(j = 0; j < 2 ; ++j) {
- if((dirp = opendir(dirname[j])) != NULL) {
- while((dp = readdir(dirp)) != NULL) {
- if ((strcmp(dp->d_name, DOT) != 0) &&
- (strcmp(dp->d_name, DOTDOT) != 0)) {
- sprintf (res_file, "%s%s", dirname[j],dp->d_name);
- if ((access (res_file, R_OK)) != 0)
- {
- Debug("LoadAltDtsResources- cant access %s.\n",
- resources);
- Debug("\t %s.\n", strerror(errno));
- continue;
- }
- if (file_count == 0) {
- file_list = malloc (list_incr * sizeof(char *));
- num_allocated += list_incr;
- }
- if (file_count + 1 > num_allocated) {
- num_allocated += list_incr;
- file_list = realloc (file_list,
- num_allocated * sizeof(char *));
- }
- file_list[file_count] = strdup (res_file);
- file_count++;
- }
- }
- closedir(dirp);
- }
- }
- if (file_count > 0)
- qsort (file_list, file_count, sizeof (char *), FileNameCompare);
- for (j = 0; j < file_count ; j++) {
- userDb = XrmGetFileDatabase(file_list[j]);
- XrmMergeDatabases(userDb,&XresourceDB);
-
- if ( XrmGetResource(XresourceDB, "Dtlogin*altDtsIncrement",
- "Dtlogin*AltDtsIncrement", &rmtype, &rmvalue ) ) {
- /*
- * remove the trailing spaces
- */
- if(strchr(rmvalue.addr,' '))
- snprintf(tempbuf, sizeof(tempbuf), "%s", strtok(rmvalue.addr," "));
- else
- snprintf(tempbuf, sizeof(tempbuf), "%s", rmvalue.addr);
- if ((strcmp(tempbuf, "True") == 0) ||
- (strcmp(tempbuf, "TRUE") == 0)) {
-
- if ( XrmGetResource(XresourceDB,
- "Dtlogin*altDtKey", "Dtlogin*AltDtKey",
- &rmtype, &rmvalue ) ) {
- ++i;
- sprintf(altdtres,"Dtlogin*altDtKey%d",i);
- XrmPutStringResource(&XresourceDB, altdtres, rmvalue.addr);
- }
- else
- continue;
-
- if ( XrmGetResource(XresourceDB,
- "Dtlogin*altDtName", "Dtlogin*AltDtName",
- &rmtype, &rmvalue ) ) {
- sprintf(altdtres,"Dtlogin*altDtName%d",i);
- XrmPutStringResource(&XresourceDB, altdtres, rmvalue.addr);
- }
- if ( XrmGetResource(XresourceDB,
- "Dtlogin*altDtStart", "Dtlogin*AltDtStart",
- &rmtype, &rmvalue ) ) {
- sprintf(altdtres,"Dtlogin*altDtStart%d",i);
- XrmPutStringResource(&XresourceDB, altdtres, rmvalue.addr);
- }
- if ( XrmGetResource(XresourceDB,
- "Dtlogin*altDtLogo", "Dtlogin*AltDtLogo",
- &rmtype, &rmvalue ) ) {
- sprintf(altdtres,"Dtlogin*altDtLogo%d",i);
- XrmPutStringResource(&XresourceDB, altdtres, rmvalue.addr);
- }
- }
- }
- }
- sprintf(tempbuf,"%d",i);
- XrmPutStringResource(&XresourceDB, "Dtlogin*altDts", tempbuf);
- if (file_count > 0) {
- for (i = 0; i < file_count; i++) {
- Debug ("Loading resource file: %s\n", file_list[i]);
- free (file_list[i]);
- }
- free (file_list);
- }
- }
- /******************
- *
- * Function Name: _ExpandLang
- *
- * Description:
- *
- * This function takes the string "string", searches for occurences of
- * "%L" in the string and if found, the "%L" is substituted with
- * the value of the $LANG environment variable.
- *
- * If $LANG is not defined, the %L is replace with NULL.
- *
- * Note:
- *
- * _ExpandLang() is based on the DtSvc _DtExpandLang() static routine.
- *
- * Synopsis:
- *
- * ret_string = _ExpandLang (string);
- *
- * char *ret_string; Returns NULL if "string" is NULL or it points
- * to the expanded string.
- *
- * char *string; The first part of the pathname. Typically
- * the directory containing the item of interest.
- *
- * Note: The caller is responsible for free'ing the returned string.
- *
- ******************/
- char *
- _ExpandLang(
- char *string,
- char *lang )
- {
- char *tmp;
- char *pch;
- char *trail;
- int n = 0;
- int lang_len = 0;
- int tmp_len;
- int i = 0;
- if (string == NULL)
- return (NULL);
- /*
- * Count the number of expansions that will occur.
- */
- for (n = 0, pch = string ; pch != NULL ; ) {
- if ((pch = strchr (pch, '%')) != NULL) {
- n++;
- pch++;
- }
- }
- if (n == 0)
- return (strdup(string));
- /*
- * We should really be calling setlocale to determine the "default"
- * locale but setlocale's return value is not standardized across
- * the various vendor platforms nor is it consistent within differnt
- * revs of individual OS's. (e.g. its changing between HP-UX 9.0 and
- * HP-UX 10.0). The "right" call would be the following line:
- *
- * if ((lang = getenv ("LANG")) || (lang = setlocale(LC_C_TYPE,NULL)))
- *
- * Here we hard code the default to "C" instead of leaving it NULL.
- */
- if (lang || (lang = getenv ("LANG")) || (lang = "C"))
- lang_len = strlen (lang);
- /*
- * Create the space needed.
- */
- tmp_len = strlen (string) + (n * lang_len) + n + 1;
- tmp = (char *) malloc (tmp_len);
- for (i = 0; i < tmp_len; tmp[i] = '\0', i++);
- pch = string;
- while (pch != NULL) {
- trail = pch;
- if ((pch = strchr (pch, '%')) != NULL) {
- pch++;
- if (pch == NULL) {
- (void) strncat (tmp, trail, ((pch - 1) - trail) + 1);
- }
- else if ((pch != NULL) && *pch == 'L') {
- if (lang_len == 0) {
- if (((pch - trail) >=2) && (*(pch-2) == '/'))
- /*
- * Remove the "/" as well as the "%L".
- */
- (void) strncat (tmp, trail, (pch - trail) - 2);
- else
- (void) strncat (tmp, trail, (pch - trail) - 1);
- }
- else {
- /*
- * Remove the "%L" and then append the LANG.
- */
- (void) strncat (tmp, trail, (pch - trail) - 1);
- (void) strcat (tmp, lang);
- }
- }
- else {
- (void) strncat (tmp, trail, (pch - trail) + 1);
- }
- if (pch != NULL)
- pch++;
- }
- else {
- /*
- * A '%' was not found.
- */
- (void) strcat (tmp, trail);
- }
- }
- return (tmp);
- }
- static void
- SetupDisplay (struct display *d)
- {
- char **env = 0, **crt_systemEnviron;
- if (d->setup && d->setup[0] && (access(d->setup, R_OK ) == 0))
- {
- crt_systemEnviron = verify.systemEnviron;
- env = systemEnv (d, (char *) 0, (char *) 0);
- if (d->authFile && strlen(d->authFile) > 0 )
- env = setEnv( env, "XAUTHORITY", d->authFile );
- if(d->displayType.location == Local)
- env = setEnv (env, LOCATION, "local");
- else
- env = setEnv (env, LOCATION, "remote");
- verify.systemEnviron = env;
- source (&verify, d->setup);
- verify.systemEnviron = crt_systemEnviron;
- freeEnv (env);
- }
- }
- /*ARGSUSED*/
- static void
- DeleteXloginResources( struct display *d, Display *dpy )
- {
- XDeleteProperty(dpy, RootWindow (dpy, 0), XA_RESOURCE_MANAGER);
- }
- #if 0 /* dead code: transferred to Dtgreet */
- static jmp_buf syncJump;
- static SIGVAL
- syncTimeout ()
- {
- longjmp (syncJump, 1);
- }
- SecureDisplay (d, dpy)
- struct display *d;
- Display *dpy;
- {
- Debug ("SecureDisplay():\n");
- signal (SIGALRM, syncTimeout);
- if (setjmp (syncJump)) {
- LogError(ReadCatalog(MC_LOG_SET,MC_LOG_NO_SECDPY,MC_DEF_LOG_NO_SECDPY),
- d->name);
- SessionExit (d, RESERVER_DISPLAY);
- }
- alarm ((unsigned) d->grabTimeout);
- Debug ("Before XGrabServer()\n");
- XGrabServer (dpy);
- if (XGrabKeyboard (dpy, DefaultRootWindow (dpy), True, GrabModeAsync,
- GrabModeAsync, CurrentTime) != GrabSuccess)
- {
- alarm (0);
- signal (SIGALRM, SIG_DFL);
- LogError(ReadCatalog(MC_LOG_SET,MC_LOG_NO_SECKEY,MC_DEF_LOG_NO_SECKEY),
- d->name);
- SessionExit (d, RESERVER_DISPLAY);
- }
- Debug ("XGrabKeyboard() succeeded\n");
- alarm (0);
- signal (SIGALRM, SIG_DFL);
- pseudoReset (dpy);
- if (!d->grabServer)
- {
- XUngrabServer (dpy);
- XSync (dpy, 0);
- }
- Debug ("Done secure %s\n", d->name);
- }
- UnsecureDisplay (d, dpy)
- struct display *d;
- Display *dpy;
- {
- Debug ("Unsecure display %s\n", d->name);
- if (d->grabServer)
- XUngrabServer (dpy);
- XSync (dpy, 0);
- }
- #endif
- #ifdef _AIX
- #ifdef _POWER
- static void
- release_aix_lic(void)
- {
- /*
- * Release AIX iFOR/LS license (if any)
- */
- int fd;
- struct pipeinfo {
- int request_type;
- pid_t login_pid;
- } release_me;
-
- release_me.request_type = -1;
- release_me.login_pid = getpid();
- if ((fd = open("/etc/security/monitord_pipe", O_RDWR, 0600)) >= 0)
- {
- write(fd, &release_me, sizeof(release_me));
- close(fd);
- }
- Debug("release message to monitord: %s\n", (fd >= 0) ? "OK" : "failed");
- }
- #endif /* _POWER */
- #endif /* _AIX */
- static void
- SessionExit( struct display *d, int status )
- {
- #ifdef _AIX
- #ifdef _POWER
- release_aix_lic();
- #endif /* _POWER */
- #endif /* _AIX */
- /* make sure the server gets reset after the session is over */
- if (d->serverPid >= 2) {
- Debug("Resetting server: pid %d signal %d\n",
- d->serverPid, d->resetSignal);
- if (d->terminateServer == 0 && d->resetSignal)
- kill (d->serverPid, d->resetSignal);
- }
- else
- ResetServer (d);
- Debug("Exiting Session with status: %d\n", status);
- exit (status);
- }
- static int
- StartClient( struct verify_info *verify, struct display *d, int *pidp )
- {
- char **f, *home;
- char currentdir[PATH_MAX+1];
- char *failsafeArgv[20];
- char *user; /* users name */
- char *lang, *font; /* failsafe LANG and font */
- int pid;
- int failsafe = FALSE; /* do we run the failsafe session? */
- int password = FALSE; /* do we run /bin/passwd? */
- int i;
- FILE *lastsession;
- char lastsessfile[MAXPATHLEN];
- #ifdef BLS
- struct pr_passwd *b1_pwd;
- #endif
- #ifdef __AFS
- #define NOPAG 0xffffffff
- long pagval, j;
- long ngroups, groups[NGROUPS];
- #endif /* __AFS */
- waitType status;
- if (verify->argv) {
- Debug ("StartSession %s: ", verify->argv[0]);
- for (f = verify->argv; *f; f++) {
- Debug ("%s ", *f);
- if ( strcmp(*f, "failsafe") == 0) failsafe = TRUE;
- if ( strcmp(*f, "password") == 0) failsafe = password = TRUE;
- }
- Debug ("; ");
- }
- if (verify->userEnviron) {
- for (f = verify->userEnviron; *f; f++)
- Debug ("%s ", *f);
- Debug ("\n");
- }
- user = getEnv (verify->userEnviron, "USER");
-
- switch (pid = fork ()) {
- case 0:
- #ifdef SIA
- /* Force a failsafe session if we can't touch the home directory
- * SIA has already attempted to chdir to HOME, and the current dir
- * will be set to / if it failed. We just check to see if the HOME
- * path is our current directory or not.
- */
- home = getEnv (verify->userEnviron, "HOME");
- getcwd(currentdir, PATH_MAX+1);
- Debug("Current directory is: %s\n", currentdir);
- #if 0
- /*
- * CDExc17917
- * The following little check doesn't really work. For example,
- * here at the XC, NIS reports my home directory as
- * "/site/guests/montyb" while getcwd comes up with
- * "/net/nexus/site/guests/montyb".
- */
- if (strcmp(home, currentdir)) {
- Debug("Can't access home directory, setting failsafe to TRUE\n");
- failsafe = TRUE;
- LogError (ReadCatalog(
- MC_LOG_SET,MC_LOG_NO_HMDIR,MC_DEF_LOG_NO_HMDIR),
- home, getEnv (verify->userEnviron, "USER"));
- verify->userEnviron = setEnv(verify->userEnviron, "HOME", "/");
- }
- #endif
- #endif /* SIA */
- CleanUpChild ();
- /*
- * do process accounting...
- */
- #if defined(PAM) || defined(SUNAUTH)
- {
- char* ttyLine = d->gettyLine;
-
- # ifdef DEF_NETWORK_DEV
- /*
- * If location is not local (remote XDMCP dtlogin) and
- * remote accouting is enabled (networkDev start with /dev/...)
- * Set tty line name to match network device for accouting.
- * Unless the resource was specifically set, default is value
- * of DEF_NETWORK_DEV define (/dev/dtremote)
- */
-
- if ( d->displayType.location != Local &&
- networkDev && !strncmp(networkDev,"/dev/",5)) {
- ttyLine = networkDev+5;
- }
- # endif
- # ifdef PAM
- PamAccounting(verify->argv[0], d->name, d->utmpId, user,
- ttyLine, getpid(), USER_PROCESS, NULL);
- # else
- solaris_accounting(verify->argv[0], d->name, d->utmpId, user,
- ttyLine, getpid(), USER_PROCESS, NULL);
- # endif
- }
- #endif
- #if !defined(sun) && !defined(CSRG_BASED)
- Account(d, user, NULL, getpid(), USER_PROCESS, status);
- #endif
- #ifdef AIXV3
- /*
- * In _AIX _POWER, the PENV_NOEXEC flag was added. This tells
- * setpenv() to set up the user's process environment and return
- * without execing. This allows us to set up the process environment
- * and proceed to the execute() call as do the other platforms.
- *
- * Unfortunately, for AIXV3, the PENV_NOEXEC does not exist, so
- * we have to pospone the setpenv() to the actual execute().
- */
- /*
- * These defines are the tag locations in userEnviron.
- * IMPORTANT: changes to the locations of these tags in verify.c
- * must be reflected here by adjusting SYS_ENV_TAG or USR_ENV_TAG.
- */
- #define SYS_ENV_TAG 0
- #define USR_ENV_TAG 3
- /*
- * Set the user's credentials: uid, gid, groups,
- * audit classes, user limits, and umask.
- * RK 09.13.93
- */
- if (setpcred(user, NULL) == -1)
- {
- Debug("Can't set User's Credentials (user=%s)\n",user);
- return (0);
- }
- #ifdef _POWER
- {
- char *usrTag, *sysTag;
- extern char **newenv;
- /*
- * Save pointers to tags. The setpenv() function clears the pointers
- * to the tags in userEnviron as a side-effect.
- */
- sysTag = verify->userEnviron[SYS_ENV_TAG];
- usrTag = verify->userEnviron[USR_ENV_TAG];
- /*
- * Set the users process environment. Store protected variables and
- * obtain updated user environment list. This call will initialize
- * global 'newenv'.
- */
- #define SESSION_PENV (PENV_INIT | PENV_ARGV | PENV_NOEXEC)
- if (setpenv(user, SESSION_PENV, verify->userEnviron, NULL) != 0)
- {
- Debug("Can't set process environment (user=%s)\n",user);
- return(0);
- }
- /*
- * Restore pointers to tags.
- */
- verify->userEnviron[SYS_ENV_TAG] = sysTag;
- verify->userEnviron[USR_ENV_TAG] = usrTag;
- /*
- * Free old userEnviron and replace with newenv from setpenv().
- */
- freeEnv(verify->userEnviron);
- verify->userEnviron = newenv;
- }
- #endif /* _POWER */
-
- #endif /* AIXV3 */
- #if defined(PAM)
- if (PamSetCred( verify->argv[0],
- user, verify->uid, verify->gid) > 0 ) {
- Debug("Can't set User's Credentials (user=%s)\n",user);
- return(0);
- }
- #endif
- #ifdef SUNAUTH
- if ( solaris_setcred(verify->argv[0],
- user, verify->uid, verify->gid) > 0 ) {
- Debug("Can't set User's Credentials (user=%s)\n",user);
- return(0);
- }
- #endif /* SUNAUTH */
- #ifndef sun
- #ifdef BLS
- /*
- * HP BLS B1 session setup...
- *
- * 1. look up user's protected account information.
- * 2. set the session sensitivity/clearance levels
- * 3. set the logical UID (LUID)
- */
- if ( ISSECURE ) {
- Debug("BLS - Setting user's clearance, security level and luid.\n");
- set_auth_parameters(1, verify->argv);
- init_security();
- verify->user_name = user;
- strncpy(verify->terminal,d->name,15);
- verify->terminal[15]='\0';
- verify->pwd = getpwnam(user);
- if ( verify->pwd == NULL || strlen(user) == 0 ) {
- LogError(ReadCatalog(
- MC_LOG_SET,MC_LOG_NO_BLSACCT,MC_DEF_LOG_NO_BLSACCT));
- exit (1);
- }
- verify->prpwd= b1_pwd = getprpwnam(user);
- verify->uid = b1_pwd->ufld.fd_uid;
-
- if ( b1_pwd == NULL || strlen(user) == 0 ) {
- LogError(ReadCatalog(
- MC_LOG_SET,MC_LOG_NO_BLSPACCT,MC_DEF_LOG_NO_BLSPACCT));
- exit (1);
- }
- /*
- * This has already been done successfully by dtgreet
- * but we need to get all the information again for the
- * dtlogin process.
- */
- if ( verify_user_seclevel(verify,sensitivityLevel) != 1 ) {
- Debug("BLS - Could not verify sensitivity level.\n");
- LogError(ReadCatalog(
- MC_LOG_SET,MC_LOG_NO_VFYLVL,MC_DEF_LOG_NO_VFYLVL));
- exit (1);
- }
- if ( change_to_user(verify) != 1 ) {
- Debug("BLS - Could not change to user: %s.\n",verify->user_name);
- LogError(ReadCatalog(
- MC_LOG_SET,MC_LOG_NO_BLSUSR,MC_DEF_LOG_NO_BLSUSR),
- verify->user_name);
- exit (1);
- }
- Debug("BLS - Session setup complete.\n");
- } else {
- #endif /* BLS */
- # ifdef __AFS
- if ( IsVerifyName(VN_AFS) ) {
- pagval = get_pag_from_groups(verify->groups[0], verify->groups[1]);
- Debug("AFS - get_pag_from_groups() returned pagval = %d\n", pagval);
- initgroups(greet.name, verify->groups[2]);
- ngroups = getgroups(NGROUPS, groups);
- Debug("AFS - getgroups() returned ngroups = %d\n", ngroups);
- for (i=0; i < ngroups; i++)
- Debug("AFS - groups[%d] = %d\n", i, groups[i]);
- if ((pagval != NOPAG) &&
- (get_pag_from_groups(groups[0], groups[1])) == NOPAG ) {
- /* we will have to shift grouplist to make room for pag */
- if (ngroups+2 > NGROUPS)
- ngroups=NGROUPS-2;
- for (j=ngroups-1; j >= 0; j--) {
- groups[j+2] = groups[j];
- }
- ngroups += 2;
- get_groups_from_pag(pagval, &groups[0], &groups[1]);
- if (setgroups(ngroups, groups) == -1) {
- LogError(
- ReadCatalog(
- MC_LOG_SET,MC_LOG_AFS_FAIL,MC_DEF_LOG_AFS_FAIL));
- exit(1);
- }
- }
- }
- # else /* ! __AFS */
- /* If SIA is enabled, the initgroups and setgid calls are redundant
- * so skip them.
- */
- # ifndef SIA
- # ifdef NGROUPS
- /*
- * if your system does not support "initgroups(3C)", use
- * the "setgroups()" call instead...
- */
-
- # if defined(__hpux)
- initgroups(user, -1);
- # else
- setgroups (verify->ngroups, verify->groups);
- # endif
- /* setpenv() will set gid for AIX */
- #if !defined (_AIX)
- if(-1 == setgid (verify->groups[0])) {
- perror(strerror(errno));
- }
- #endif
- # else /* ! NGROUPS */
- /* setpenv() will set gid for AIX */
- #if !defined (_AIX)
- setgid (verify->gid);
- #endif
- # endif /* NGROUPS */
- # endif /* !SIA */
- # endif /* __AFS */
- # ifdef AUDIT
- setaudid(verify->audid);
- setaudproc(verify->audflg);
- # endif
- /* setpenv() will set uid for AIX */
- #if !defined(_AIX)
- if (setuid(verify->uid) != 0) {
- Debug( "Setuid failed for user %s, errno = %d\n", user, errno);
- LogError(ReadCatalog(
- MC_LOG_SET,MC_LOG_FAIL_SETUID,MC_DEF_LOG_FAIL_SETUID),
- user,errno);
- exit (1);
- }
- #endif
- #ifdef BLS
- } /* ends the else clause of if ( ISSECURE ) */
- #endif /* BLS */
- #endif /* ! sun */
-
- /*
- * check home directory again...
- */
- #ifndef SIA
- /* Don't need to do this if SIA is enabled, already been done.
- */
- home = getEnv (verify->userEnviron, "HOME");
- if (home) {
- if (chdir (home) == -1) {
- LogError (ReadCatalog(
- MC_LOG_SET,MC_LOG_NO_HMDIR,MC_DEF_LOG_NO_HMDIR),
- home, getEnv (verify->userEnviron, "USER"));
- if(-1 == chdir ("/")) {
- perror(strerror(errno));
- }
- verify->userEnviron = setEnv(verify->userEnviron,
- "HOME", "/");
- }
- else if(!failsafe) {
- strcpy(lastsessfile,home); /* save user's last session */
- strcat(lastsessfile,LAST_SESSION_FILE);
- if((lastsession = fopen(lastsessfile,"w")) == NULL)
- Debug("Unable to open file for writing: %s\n",lastsessfile);
- else{
- fputs(verify->argv[0],lastsession);
- fclose(lastsession);
- }
- }
- }
- #endif
- SetUserAuthorization (d, verify);
- /*
- * clear password...
- */
- if (greet.password)
- bzero(greet.password, strlen(greet.password));
- #ifdef BLS
- /*
- * Write login information to a file
- * The file name should really be settable by some kind of resource
- * but time is short so we hard-wire it to ".dtlogininfo".
- */
- if ( ! writeLoginInfo( ".dtlogininfo" , verify ) )
- Debug("Unable to write \".dtlogininfo\"\n");
- # ifndef NDEBUG
- /* extra debugging */
- if(!dump_sec_debug_info(verify)) {
- Debug("Something wrong with environment\n");
- exit(1);
- }
- # endif /* ! NDEBUG */
- #endif /* BLS */
- /*
- * exec session...
- */
- if (verify->argv) {
- if ( !failsafe) {
- Debug ("Executing session %s\n", verify->argv[0]);
- execute (verify->argv, verify->userEnviron);
- LogError(ReadCatalog(
- MC_LOG_SET,MC_LOG_SES_EXEFAIL,MC_DEF_LOG_SES_EXEFAIL),
- verify->argv[0]);
- }
- } else {
- LogError(ReadCatalog(
- MC_LOG_SET,MC_LOG_NO_CMDARG,MC_DEF_LOG_NO_CMDARG));
- }
-
-
- /*
- * specify a font for the multi-byte languages...
- */
-
- font = NULL;
- lang = getEnv (verify->userEnviron, "LANG");
- i = 0;
- if ( password ) {
- #if defined(_AIX)
- failsafeArgv[i++] = "/usr/bin/X11/aixterm";
- #elif defined(sun)
- failsafeArgv[i++] = "/usr/openwin/bin/xterm";
- #elif defined(__hpux)
- failsafeArgv[i++] = "/usr/bin/X11/hpterm";
- #elif defined(__OpenBSD__)
- failsafeArgv[i++] = "/usr/X11R6/bin/xterm";
- #elif defined(__NetBSD__)
- failsafeArgv[i++] = "/usr/X11R7/bin/xterm";
- #elif defined(__FreeBSD__)
- failsafeArgv[i++] = "/usr/local/bin/xterm";
- #else
- failsafeArgv[i++] = "/usr/bin/X11/xterm";
- #endif
- failsafeArgv[i++] = "-geometry";
- failsafeArgv[i++] = "80x10";
- failsafeArgv[i++] = "-bg";
- failsafeArgv[i++] = "white";
- failsafeArgv[i++] = "-fg";
- failsafeArgv[i++] = "black";
- #ifdef _AIX
- /* aixterm requires -lang option. */
- failsafeArgv[i++] = "-lang";
- failsafeArgv[i++] = lang;
- #else /* _AIX */
- failsafeArgv[i++] = "-fn";
- if (font == NULL) font = "fixed";
- failsafeArgv[i++] = font;
- #endif /* _AIX */
- failsafeArgv[i++] = "-e";
- failsafeArgv[i++] = "/bin/passwd";
- #if defined(__PASSWD_ETC)
- failsafeArgv[i++] = "-n";
- #endif
- failsafeArgv[i++] = getEnv (verify->userEnviron, "USER");
- }
- else {
- failsafeArgv[i++] = d->failsafeClient;
- #ifdef sun
- failsafeArgv[i++] = "-C";
- #endif
- failsafeArgv[i++] = "-ls";
- if (font != NULL) {
- failsafeArgv[i++] = "-fn";
- failsafeArgv[i++] = font;
- }
- }
- failsafeArgv[i] = 0;
- Debug ("Executing failsafe session\n", failsafeArgv[0]);
- execute (failsafeArgv, verify->userEnviron);
- exit (1);
- case -1:
- Debug ("StartSession(): fork failed\n");
- LogError(ReadCatalog(MC_LOG_SET,MC_LOG_NO_SESFORK,MC_DEF_LOG_NO_SESFORK),
- d->name);
- return 0;
- default:
- Debug ("StartSession(): fork succeeded, pid = %d\n", pid);
- *pidp = pid;
- return 1;
- }
- }
- static jmp_buf tenaciousClient;
- static SIGVAL
- waitAbort( int arg )
- {
- longjmp (tenaciousClient, 1);
- }
- #if defined(SYSV) || defined(SVR4)
- # include <ctype.h>
- #define killpg(pgrp, sig) kill(-(pgrp), sig)
- #endif /* SYSV */
- static int
- AbortClient( int pid )
- {
- int sig = SIGTERM;
- #ifdef __STDC__
- volatile int i;
- #else
- int i;
- #endif
- int retId;
- for (i = 0; i < 4; i++) {
- if (killpg (pid, sig) == -1) {
- switch (errno) {
- case EPERM:
- LogError(ReadCatalog(
- MC_LOG_SET,MC_LOG_NO_KILLCL,MC_DEF_LOG_NO_KILLCL));
- case EINVAL:
- case ESRCH:
- return 0;
- }
- }
- if (!setjmp (tenaciousClient)) {
- (void) signal (SIGALRM, waitAbort);
- (void) alarm ((unsigned) 10);
- retId = wait ((waitType *) 0);
- (void) alarm ((unsigned) 0);
- (void) signal (SIGALRM, SIG_DFL);
- if (retId == pid)
- break;
- } else
- signal (SIGALRM, SIG_DFL);
- sig = SIGKILL;
- }
- return 1;
- }
- int
- source( struct verify_info *verify, char *file )
- {
- char *args[2];
- int pid;
- waitType result;
- if (file && file[0]) {
- Debug ("Source(): %s\n", file);
- switch (pid = fork ()) {
- case 0:
- CleanUpChild ();
- args[0] = file;
- args[1] = NULL;
- execute (args, verify->systemEnviron);
- LogError(ReadCatalog(
- MC_LOG_SET,MC_LOG_NO_EXE,MC_DEF_LOG_NO_EXE),args[0]);
- exit (1);
- case -1:
- Debug ("Source(): fork failed\n");
- LogError(ReadCatalog(
- MC_LOG_SET,MC_LOG_NO_FORK,MC_DEF_LOG_NO_FORK),file);
- return 1;
- break;
- default:
- while (wait (&result) != pid)
- ;
- break;
- }
- return waitVal (result);
- }
- return 0;
- }
- /* returns 0 on failure, -1 on out of mem, and 1 on success */
- int
- execute(char **argv, char **environ )
- {
- /*
- * make stdout follow stderr to the log file...
- */
- dup2 (2,1);
-
- session_execve (argv[0], argv, environ);
- /*
- * In case this is a shell script which hasn't been made executable
- * (or this is a SYSV box), do a reasonable thing...
- */
- #ifdef _AIX
- /* errno is EACCES if not executable */
- if (errno == ENOEXEC || errno == EACCES) {
- #else /* _AIX */
- if (errno == ENOEXEC) {
- #endif /* _AIX */
- char program[1024], *e, *p, *optarg;
- FILE *f;
- char **newargv, **av;
- int argc;
- /*
- * emulate BSD kernel behaviour -- read
- * the first line; check if it starts
- * with "#!", in which case it uses
- * the rest of the line as the name of
- * program to run. Else use "/bin/sh".
- */
- f = fopen (argv[0], "r");
- if (!f)
- return 0;
- if (fgets (program, sizeof (program) - 1, f) == NULL)
- {
- fclose (f);
- return 0;
- }
- fclose (f);
- e = program + strlen (program) - 1;
- if (*e == '\n')
- *e = '\0';
- if (!strncmp (program, "#!", 2)) {
- p = program + 2;
- while (*p && isspace (*p))
- ++p;
- optarg = p;
- while (*optarg && !isspace (*optarg))
- ++optarg;
- if (*optarg) {
- *optarg = '\0';
- do
- ++optarg;
- while (*optarg && isspace (*optarg));
- } else
- optarg = 0;
- } else {
- p = "/bin/sh";
- optarg = 0;
- }
- Debug ("Shell script execution: %s (optarg %s)\n",
- p, optarg ? optarg : "(null)");
- for (av = argv, argc = 0; *av; av++, argc++)
- ;
- newargv = (char **) malloc ((argc + (optarg ? 3 : 2)) * sizeof (char *));
- if (!newargv)
- return -1;
- av = newargv;
- *av++ = p;
- if (optarg)
- *av++ = optarg;
- while (*av++ = *argv++)
- ;
- session_execve (newargv[0], newargv, environ);
- }
- return 1;
- }
- /*****************************************************************************
- * RunGreeter
- *
- * Invoke the Greeter process and wait for completion. If the user was
- * successfully verified, return to the calling process. If the user
- * selected a restart or abort option, or there was an error invoking the
- * Greeter, exit this entire process with appropriate status.
- *
- *****************************************************************************/
- #define MSGSIZE 512
- extern int session_set;
- extern char *progName; /* Global argv[0]; dtlogin name and path */
- int response[2], request[2];
- /* Fixes problem with dtlogin signal handling */
- static int greeterPid = 0;
- static struct display *greeter_d = NULL;
- static SIGVAL
- catchHUP(int arg)
- {
- Debug("Caught SIGHUP\n");
- if (greeterPid)
- {
- Debug("Killing greeter process: %d\n", greeterPid);
- kill(greeterPid, SIGHUP);
- }
- if (greeter_d)
- SessionExit(greeter_d, REMANAGE_DISPLAY);
- else
- exit(REMANAGE_DISPLAY);
- }
- static void
- RunGreeter( struct display *d, struct greet_info *greet,
- struct verify_info *verify )
- {
- int pid;
- waitType status;
-
- int rbytes;
- static char msg[MSGSIZE];
- char *p;
- char **env;
- char *path;
- struct greet_state state;
- int notify_dt;
- int dupfp = -1;
- int dupfp2 = -1;
- #ifdef __PASSWD_ETC
- # ifndef U_NAMELEN
- # define U_NAMELEN sizeof(rgy_$name_t)
- # endif
- int i;
- static char name_short[U_NAMELEN];
- #endif
- #ifdef SIA
- int argc = 1;
- char *argv[] = { "dtlogin", 0 };
- char *hostName = NULL;
- char *loginName = NULL;
- int siaStatus = -1;
- /*
- * Initialize SIA
- */
-
- if (d->serverPid == -1)
- hostName = d->name;
- siaStatus = sia_ses_init(&siaHandle, argc, argv, hostName,
- loginName, d->name, 1, NULL);
- if (siaStatus != SIASUCCESS)
- {
- Debug("sia_ses_init failure status %d\n", siaStatus);
- exit(1);
- }
- #endif
- greeterPid = 0;
- if (!setjmp (abortSession)) {
- signal(SIGTERM, catchTerm);
- /*
- * We've changed dtlogin to pass HUP's down to the children
- * so ignore any HUP's once the client has started.
- */
- greeter_d = d;
- signal(SIGHUP, catchHUP);
- /*
- * set up communication pipes...
- */
-
- if(-1 == pipe(response)) {
- perror(strerror(errno));
- }
- if(-1 == pipe(request)) {
- perror(strerror(errno));
- }
- rbytes = 0;
- switch (greeterPid = fork ()) {
- case 0:
- /*
- * pass some information in the environment...
- */
-
- env = 0;
- sprintf(msg,"%d", d->grabServer);
- env = setEnv(env, GRABSERVER, msg);
-
- sprintf(msg,"%d", d->grabTimeout);
- env = setEnv(env, GRABTIMEOUT, msg);
- if (timeZone && strlen(timeZone) > 0 )
- env = setEnv(env, "TZ", timeZone);
- if (errorLogFile && errorLogFile[0])
- env = setEnv(env, ERRORLOG, errorLogFile);
- if (d->authFile)
- env = setEnv(env, "XAUTHORITY", d->authFile);
- if (d->dtlite)
- env = setEnv(env, DTLITE, "True");
- if (d->session)
- env = setEnv(env, SESSION, d->session);
- if(session_set)
- env = setEnv(env, SESSION_SET, "True");
- if (d->pmSearchPath)
- env = setEnv(env, "XMICONSEARCHPATH", d->pmSearchPath);
- if (d->bmSearchPath)
- env = setEnv(env, "XMICONBMSEARCHPATH", d->bmSearchPath);
- #if defined (__KERBEROS) || defined (__AFS)
- if (d->verifyName) {
- if ( (strcmp(d->verifyName, VN_AFS) == 0) ||
- (strcmp(d->verifyName, VN_KRB) == 0) ) {
-
- env = setEnv(env, VERIFYNAME, d->verifyName );
- }
- else {
- LogError(ReadCatalog(
- MC_LOG_SET,MC_LOG_IMPROP_AUTH,MC_DEF_LOG_IMPROP_AUTH),
- d->verifyName);
- d->verifyName = NULL;
- }
- }
- #endif
-
- if((path = getenv("NLSPATH")) != NULL)
- env = setEnv(env, "NLSPATH", path);
-
- /*
- * ping remote displays...
- *
- */
- if (d->displayType.location == Local) {
- GettyRunning(d); /* refresh gettyState */
- if (d->gettyState != DM_GETTY_USER)
- env = setEnv(env, LOCATION, "local");
- }
- else {
- sprintf(msg,"%d", d->pingInterval);
- env = setEnv(env, PINGINTERVAL, msg);
-
- sprintf(msg,"%d", d->pingTimeout);
- env = setEnv(env, PINGTIMEOUT, msg);
- }
- if ( d->langList && strlen(d->langList) > 0 )
- env = setEnv(env, LANGLIST, d->langList);
- #if !defined (ENABLE_DYNAMIC_LANGLIST)
- else if (strlen(languageList) > 0 )
- env = setEnv(env, LANGLIST, languageList);
- #endif /* ENABLE_DYNAMIC_LANGLIST */
- {
- char *language = NULL;
- #if defined (ENABLE_DYNAMIC_LANGLIST)
- language = d->language;
- #endif /* ENABLE_DYNAMIC_LANGLIST */
- if (env && d->language && strlen(d->language) > 0 )
- env = setLang(d, env, language);
- }
- if((path = getenv("XKEYSYMDB")) != NULL)
- env = setEnv(env, "XKEYSYMDB", path);
- #ifdef sun
- if((path = getenv("OPENWINHOME")) != NULL)
- env = setEnv(env, "OPENWINHOME", path);
- #endif
- Debug ("Greeter environment:\n");
- printEnv(env);
- Debug ("End of Greeter environment:\n");
- /*
- * Writing to file descriptor 1 goes to response pipe instead.
- */
- close(1);
- dupfp = dup(response[1]);
- if(-1 == dupfp) {
- perror(strerror(errno));
- }
- close(response[0]);
- close(response[1]);
- /*
- * Reading from file descriptor 0 reads from request pipe instead.
- */
- close(0);
- dupfp2 = dup(request[0]);
- if(-1 == dupfp2) {
- perror(strerror(errno));
- }
- close(request[0]);
- close(request[1]);
- CleanUpChild ();
- /*
- * figure out path to dtgreet...
- */
- snprintf(msg, sizeof(msg), "%s", progName);
-
- if ((p = (char *) strrchr(msg, '/')) == NULL)
- strcpy(msg,"./");
- else
- *(++p) = '\0';
- strcat(msg,"dtgreet");
- execle(msg, "dtgreet", "-display", d->name, (char *)0, env);
- LogError(ReadCatalog(
- MC_LOG_SET,MC_LOG_NO_DTGREET,MC_DEF_LOG_NO_DTGREET),
- msg, d->name);
- exit (NOTIFY_ABORT_DISPLAY);
- case -1:
- Debug ("Fork of Greeter failed.\n");
- LogError(ReadCatalog(
- MC_LOG_SET,MC_LOG_NO_FORKCG,MC_DEF_LOG_NO_FORKCG),d->name);
- close(request[0]);
- close(request[1]);
- close(response[0]);
- close(response[1]);
- exit (UNMANAGE_DISPLAY);
- default:
- Debug ("Greeter started\n");
- close(response[1]); /* Close write end of response pipe */
- close(request[0]); /* Close read end of request pipe */
- /*
- * Retrieve information from greeter and authenticate.
- */
- globalDisplayName = d->name;
- state.id = GREET_STATE_ENTER;
- state.waitForResponse = FALSE;
- #ifdef SIA
-
- /*
- * atexit() registers this function to be called if exit() is
- * called. This is needed because in enhanced security mode, SIA
- * may call exit() whn the user fails to enter or change a
- * password.
- */
- sia_greeter_pid = greeterPid;
- if (!sia_exit_proc_reg)
- {
- atexit(KillGreeter);
- sia_exit_proc_reg = TRUE;
- }
-
- siaGreeterInfo.d = d;
- siaGreeterInfo.greet = greet;
- siaGreeterInfo.verify = verify;
- siaGreeterInfo.state = &state;
- siaGreeterInfo.status = TRUE;
-
- siaStatus = -1;
- while(siaStatus != SIASUCCESS)
- {
- while(siaStatus != SIASUCCESS && siaGreeterInfo.status)
- {
- Debug ("RunGreeter: before sia_ses_authent\n");
- dt_in_sia_ses_authent = True;
- siaStatus = sia_ses_authent(SiaManageGreeter, NULL,
- siaHandle);
- dt_in_sia_ses_authent = False;
- Debug ("RunGreeter: after sia_ses_authent status = %d\n",
- siaStatus);
- if (siaStatus == SIAFAIL && siaGreeterInfo.status)
- {
- state.id = GREET_STATE_ERRORMESSAGE;
- state.vf = VF_INVALID;
- ManageGreeter(d, greet, verify, &state);
- }
- if (!siaGreeterInfo.status || siaStatus == SIASTOP)
- break;
- }
- if (!siaGreeterInfo.status || siaStatus == SIASTOP)
- {
- sia_ses_release(&siaHandle);
- break;
- }
-
- Debug("RunGreeter: before sia_ses_estab\n");
- siaStatus = sia_ses_estab(SiaManageGreeter, siaHandle);
- Debug ("RunGreeter: after sia_ses_estab status = %d\n",
- siaStatus);
-
- if (!siaGreeterInfo.status)
- break;
-
- if (siaStatus == SIASUCCESS)
- {
- Debug("RunGreeter: before sia_ses_launch\n");
- siaStatus = sia_ses_launch(SiaManageGreeter, siaHandle);
- Debug("RunGreeter: after sia_ses_launch status = %d\n",
- siaStatus);
- }
- if (!siaGreeterInfo.status)
- break;
-
- if (siaStatus != SIASUCCESS)
- {
- Debug("RunGreeter: sia_ses_launch failure\n");
- /* establish & launch failures do a release */
- siaHandle = NULL;
- siaStatus = sia_ses_init(&siaHandle, argc, argv, hostName,
- loginName, d->name, 1, NULL);
- if (siaStatus != SIASUCCESS)
- {
- Debug("sia_ses_init failure status %d\n", siaStatus);
- exit(RESERVER_DISPLAY);
- }
- }
- }
- /*
- * sia_ses_launch() wil probably seteuid to that of the
- * user, but we don't want that now.
- */
- seteuid(0);
- /*
- * extract necessary info from SIA context struct
- */
- if (siaHandle)
- {
- if (siaStatus == SIASUCCESS)
- CopySiaInfo(siaHandle, greet);
- sia_ses_release(&siaHandle);
- }
- state.id = GREET_STATE_TERMINATEGREET;
- if (siaGreeterInfo.status)
- {
- while (ManageGreeter(d, greet, verify, &state))
- ;
- }
- sia_greeter_pid = 0;
- #else
- while (ManageGreeter(d, greet, verify, &state))
- ;
- #endif /* SIA */
- /*
- * Wait for Greeter to end...
- */
- for (;;) {
- pid = wait (&status);
- if (pid == greeterPid)
- break;
- }
- /*
- * Greeter exited. Check return code...
- */
-
- Debug("Greeter return status; exit = %d, signal = %d\n",
- waitCode(status), waitSig(status));
- /*
- * remove authorization file if used...
- */
-
- if (d->authorizations && d->authFile &&
- waitVal(status) != NOTIFY_LANG_CHANGE
- #ifdef BLS
- && waitVal(status) != NOTIFY_BAD_SECLEVEL
- #endif
- ) {
- /***
- Debug ("Done with authorization file %s, removing\n",
- d->authFile);
- (void) unlink (d->authFile);
- ***/
- }
- if(waitVal(status) > NOTIFY_ALT_DTS)
- d->sessionType = waitVal(status);
- switch (waitVal(status)) {
- case NOTIFY_FAILSAFE:
- greet->string = "failsafe";
- break;
- case NOTIFY_PASSWD_EXPIRED:
- greet->string = "password";
- break;
- case NOTIFY_DTLITE:
- case NOTIFY_DT:
- case NOTIFY_OK:
- case NOTIFY_LAST_DT:
- d->sessionType = waitVal(status);
- break;
- default:
- break;
- }
- Debug("waitVal - status is %d\n", waitVal(status));
- if(waitVal(status) > NOTIFY_ALT_DTS)
- notify_dt = NOTIFY_ALT_DTS; /* It is alt desktops */
- else
- notify_dt = waitVal(status);
- switch (notify_dt) {
- case NOTIFY_FAILSAFE:
- case NOTIFY_PASSWD_EXPIRED:
- case NOTIFY_DTLITE:
- case NOTIFY_DT:
- case NOTIFY_OK:
- case NOTIFY_LAST_DT:
- case NOTIFY_ALT_DTS:
- if (NULL == greet->name) return;
- /*
- * greet->name, greet->password set in ManageGreeter().
- */
- Debug("Greeter returned name '%s'\n", greet->name);
- #ifdef __PASSWD_ETC
- greet->name_full = greet->name;
- /* get just person name out of full SID */
- i = 0;
- while (i < sizeof(rgy_$name_t)
- && greet->name_full[i] != '.'
- && greet->name_full[i] != '\0') {
- name_short[i] = greet->name_full[i];
- i++;
- }
- name_short[i] = '\0';
- greet->name = name_short;
- #endif
-
- #ifdef __AFS
- /*
- * groups[] set in Authenticate().
- */
- if ( IsVerifyName(VN_AFS) ) {
- verify->groups[0] = groups[0];
- verify->groups[1] = groups[1];
- Debug("Greeter returned groups[0] '%d'\n", verify->groups[0]);
- Debug("Greeter returned groups[1] '%d'\n", verify->groups[1]);
- }
- #endif
-
- #ifdef BLS
- /*
- * sensitivityLevel set in BLS_Verify()
- */
- greet->b1security = sensitivityLevel;
- #endif
- Verify(d, greet, verify);
- return;
- case NOTIFY_ABORT:
- Debug ("Greeter Xlib error or SIGTERM\n");
- SessionExit(d, OPENFAILED_DISPLAY);
- case NOTIFY_RESTART:
- Debug ("Greeter requested RESTART_DISPLAY\n");
- SessionExit(d, RESERVER_DISPLAY);
- case NOTIFY_ABORT_DISPLAY:
- Debug ("Greeter requested UNMANAGE_DISPLAY\n");
- SessionExit(d, UNMANAGE_DISPLAY);
- case NOTIFY_NO_WINDOWS:
- Debug ("Greeter requested NO_WINDOWS mode\n");
- if (d->serverPid >= 2)
- /*
- * Don't do a SessionExit() here since that causes
- * the X-server to be reset. We know we are going to
- * terminate it anyway, so just go do that...
- */
- exit(SUSPEND_DISPLAY);
- else
- return;
- case NOTIFY_LANG_CHANGE:
- Debug ("Greeter requested LANG_CHANGE\n");
- /*
- * copy requested language into display struct "d". Note,
- * this only happens in this child's copy of "d", not in
- * the master struct. When the user logs out, the
- * resource-specified language (if any) will reactivate.
- */
- if (d->language)
- Debug("Greeter returned language '%s'\n", d->language);
- else
- Debug("Greeter returned language (NULL)\n");
- if (strcmp(d->language, "default") == 0) {
- int len = strlen(defaultLanguage) + 1;
- d->language = (d->language == NULL ?
- malloc(len) : realloc (d->language, len));
- strcpy(d->language, defaultLanguage);
- }
- return;
- #ifdef BLS
- case NOTIFY_BAD_SECLEVEL:
- return;
- #endif
- case waitCompose (SIGTERM,0,0):
- Debug ("Greeter exited on SIGTERM\n");
- SessionExit(d, OPENFAILED_DISPLAY);
-
- default:
- Debug ("Greeter returned unknown status %d\n",
- waitVal(status));
- SessionExit(d, REMANAGE_DISPLAY);
- }
- }
- signal(SIGHUP, SIG_DFL);
- }
- else {
- AbortClient(greeterPid);
- SessionExit(d, UNMANAGE_DISPLAY);
- }
- }
- /*****************************************************************************
- * ManageGreeter
-
- State transitions
-
- enter -> ENTER:
- This is the entry into greeter state processing. Allocate and initialize
- state structure.
- ENTER -> LOGIN:
- Display the login screen. Upon display, the login screen can be 'reset'. If
- reset is true, the username and password fields are cleared and the focus
- is set to the username field. If reset is false, the username and password
- field is untouched and the focus is set to the password field.
- LOGIN -> AUTHENTICATE:
- Authenticate the username entered on login screen.
- AUTHENTICATE -> TERMINATEGREET:
- User passed authentication so terminate the greeter.
- AUTHENTICATE -> EXPASSWORD:
- User passed authentication, but the their password has expired.
- Display old password message. This message allows the user to
- change their password by starting a getty and running passwd(1).
- AUTHENTICATE -> BAD_HOSTNAME:
- User passed authentication, but the their hostname is empty.
- Display a dialog that allows the user to run a getty to fix the
- problem, or start the desktop anyway.
- AUTHENTICATE -> ERRORMESSAGE:
- User failed authentication, so display error message.
- AUTHENTICATE -> LOGIN
- User failed authentication, but did not enter a password. Instead
- of displaying an error message, redisplay the login screen with
- the focus set to the password field. If the user authenticates again
- without the password field set, display an error. This allows a user
- to type the ubiquitous "username<ENTER>password<ENTER>" sequence.
- EXIT -> exit
- Free state structure and return false to stop state transitions.
- ERRORMESSAGE -> LOGIN
- Display error message base on return code from last authentication
- attempt. Redisplay login screen with reset set to true.
- (state) -> LANG -> (state)
- User has chosen a new language. Transition to LANG state to save off
- the new language, and transition back to original state.
-
- *****************************************************************************/
- #define SETMC(M, ID) M.id = MC_##ID; M.def = MC_DEF_##ID
- static int
- ManageGreeter( struct display *d, struct greet_info *greet,
- struct verify_info *verify, struct greet_state *state )
- {
- struct {
- int id;
- char *def;
- } msg;
- if (state->waitForResponse)
- {
- if (!AskGreeter(NULL, (char *)state->response, REQUEST_LIM_MAXLEN))
- {
- /*
- * Dtgreet has terminated.
- */
- state->id = GREET_STATE_EXIT;
- state->waitForResponse = FALSE;
- return(TRUE);
- }
- if (state->request->opcode != state->response->opcode)
- {
- /*
- * An unrequested event arrived. See if it's one we
- * are expecting.
- */
- switch(state->response->opcode)
- {
- case REQUEST_OP_LANG:
- {
- /*
- * User has changed language. Recursively handle this state
- * and return to current state.
- */
- struct greet_state lang_state;
- lang_state = *state;
- lang_state.id = GREET_STATE_LANG;
- lang_state.waitForResponse = FALSE;
- ManageGreeter(d, greet, verify, &lang_state);
- Debug("Response opcode REQUEST_OP_LANG\n");
- return(TRUE);
- }
- break;
- case REQUEST_OP_CLEAR:
- {
- /*
- * User has requested the screen be cleared.
- */
- state->id = GREET_STATE_USERNAME;
- state->waitForResponse = TRUE;
- Debug("Response opcode REQUEST_OP_CLEAR\n");
- }
- break;
-
- default:
- Debug("Response opcode UNEXPECTED RESPONSE!\n");
- #ifndef SIA
- return(TRUE);
- #endif
- break;
- }
- }
- else
- {
- /*
- * Got the response we were expecting.
- */
- state->waitForResponse = FALSE;
- }
- }
- switch(state->id)
- {
- case GREET_STATE_ENTER:
- {
- /*
- * Enter - initialize state
- */
- Debug("GREET_STATE_ENTER\n");
- state->request = (RequestHeader *)malloc(REQUEST_LIM_MAXLEN);
- state->response= (ResponseHeader *)malloc(REQUEST_LIM_MAXLEN);
- state->authenticated = FALSE;
- state->msg = NULL;
- state->id = GREET_STATE_USERNAME;
- }
- break;
- case GREET_STATE_USERNAME:
- {
- /*
- * Get user name
- */
- RequestChallenge *r;
- Debug("GREET_STATE_USERNAME\n");
- Authenticate(d, NULL, NULL, NULL);
- SETMC(msg, LOGIN_LABEL);
- r = (RequestChallenge *)state->request;
- r->hdr.opcode = REQUEST_OP_CHALLENGE;
- r->hdr.reserved = 0;
- r->bEcho = TRUE;
- r->idMC = msg.id;
- r->hdr.length = sizeof(*r);
- r->offChallenge = sizeof(*r);
- strcpy(((char *)r) + r->offChallenge, msg.def);
- r->hdr.length += strlen(msg.def) + 1;
- if (greet->name)
- {
- r->offUserNameSeed = r->hdr.length;
- strcpy(((char *)r) + r->offUserNameSeed, greet->name);
- r->hdr.length += strlen(greet->name) + 1;
- Debug("Greet name: %s\n", greet->name);
- }
- else
- {
- r->offUserNameSeed = 0;
- }
- if (greet->name)
- {
- free(greet->name); greet->name = NULL;
- }
- if (greet->password)
- {
- free(greet->password); greet->password = NULL;
- }
- TellGreeter((RequestHeader *)r);
- state->waitForResponse = TRUE;
- state->id = GREET_STATE_AUTHENTICATE;
- }
- break;
- case GREET_STATE_CHALLENGE:
- {
- /*
- * Get user name
- */
- RequestChallenge *r;
- Debug("GREET_STATE_CHALLENGE\n");
- if (greet->password)
- {
- free(greet->password); greet->password = NULL;
- }
- SETMC(msg, PASSWD_LABEL);
- r = (RequestChallenge *)state->request;
- r->hdr.opcode = REQUEST_OP_CHALLENGE;
- r->hdr.reserved = 0;
- r->bEcho = FALSE;
- r->idMC = msg.id;
- r->offUserNameSeed = 0;
- r->offChallenge = sizeof(*r);
- strcpy(((char *)r) + r->offChallenge, msg.def);
- r->hdr.length = sizeof(*r) + strlen(msg.def) + 1;
- TellGreeter((RequestHeader *)r);
- state->waitForResponse = TRUE;
- state->id = GREET_STATE_AUTHENTICATE;
- }
- break;
- case GREET_STATE_AUTHENTICATE:
- {
- /*
- * Attempt to authenticate.
- */
- ResponseChallenge *r;
-
- Debug("GREET_STATE_AUTHENTICATE\n");
- r = (ResponseChallenge *)state->response;
-
- if (greet->name == NULL)
- {
- greet->name = strdup(((char *)r) + r->offResponse);
- if (strlen(greet->name) == 0)
- {
- state->id = GREET_STATE_USERNAME;
- break;
- }
- }
- else
- {
- greet->password = strdup(((char *)r) + r->offResponse);
- }
- if (state->msg)
- {
- free(state->msg);
- state->msg = NULL;
- }
- /*
- * Attempt to authenticate user. 'username' should be a
- * non-empty string. 'password' may be an empty string.
- */
- state->vf = Authenticate(d, greet->name, greet->password, &state->msg);
- if (state->vf == VF_OK ||
- state->vf == VF_PASSWD_AGED ||
- state->vf == VF_BAD_HOSTNAME)
- {
- state->authenticated = TRUE;
- }
- /*
- * General transitions.
- */
- switch (state->vf)
- {
- case VF_OK: state->id = GREET_STATE_TERMINATEGREET; break;
- case VF_PASSWD_AGED: state->id = GREET_STATE_EXPASSWORD; break;
- case VF_BAD_HOSTNAME: state->id = GREET_STATE_BAD_HOSTNAME; break;
- case VF_CHALLENGE: state->id = GREET_STATE_CHALLENGE; break;
- default: state->id = GREET_STATE_ERRORMESSAGE; break;
- }
- }
- break;
- case GREET_STATE_EXIT:
- {
- /*
- * Free resources and leave.
- */
- Debug("GREET_STATE_EXIT\n");
- if (state->msg)
- {
- free(state->msg);
- }
-
- if (!state->authenticated)
- {
- if (greet->name)
- {
- free(greet->name); greet->name = NULL;
- }
- if (greet->password)
- {
- free(greet->password); greet->password = NULL;
- }
- }
- free(state->request);
- free(state->response);
- return(FALSE);
- }
- break;
- case GREET_STATE_ERRORMESSAGE:
- {
- /*
- * Display error message.
- */
- RequestMessage *r;
- Debug("GREET_STATE_ERRORMESSAGE\n");
- r = (RequestMessage *)state->request;
- switch(state->vf)
- {
- case VF_INVALID: SETMC(msg, LOGIN); break;
- case VF_HOME: SETMC(msg, HOME); break;
- case VF_MAX_USERS: SETMC(msg, MAX_USERS); break;
- case VF_BAD_UID: SETMC(msg, BAD_UID); break;
- case VF_BAD_GID: SETMC(msg, BAD_GID); break;
- case VF_BAD_AID: SETMC(msg, BAD_AID); break;
- case VF_BAD_AFLAG: SETMC(msg, BAD_AFLAG); break;
- case VF_NO_LOGIN: SETMC(msg, NO_LOGIN); break;
- #ifdef BLS
- case VF_BAD_SEN_LEVEL: SETMC(msg, BAD_SEN_LEVEL); break;
- #endif
- case VF_MESSAGE: msg.id=0; msg.def=state->msg; break;
- default: msg.id=0; msg.def=""; break;
- }
- r->hdr.opcode = REQUEST_OP_MESSAGE;
- r->hdr.reserved = 0;
- r->idMC = msg.id;
- r->offMessage = sizeof(*r);
- strcpy(((char *)r) + r->offMessage, msg.def);
- r->hdr.length = sizeof(*r) + strlen(msg.def) + 1;
- TellGreeter((RequestHeader *)r);
- state->waitForResponse = TRUE;
- state->id = GREET_STATE_USERNAME;
- }
- break;
- case GREET_STATE_LANG:
- {
- /*
- * User selected new language.
- */
- ResponseLang *r;
- char *lang;
- int len;
- Debug("GREET_STATE_LANG\n");
- r = (ResponseLang *)state->response;
- lang = ((char *)r) + r->offLang;
- len = strlen(lang) + 1;
- d->language = (d->language == NULL ?
- malloc(len) : realloc(d->language, len));
- strcpy(d->language, lang);
- Debug("Language returned: %s\n", d->language);
- }
- break;
- case GREET_STATE_TERMINATEGREET:
- {
- /*
- * Terminate dtgreet.
- */
- RequestExit *r;
- Debug("GREET_STATE_TERMINATEGREET\n");
- r = (RequestExit *)state->request;
- r->hdr.opcode = REQUEST_OP_EXIT;
- r->hdr.reserved = 0;
- r->hdr.length = sizeof(*r);
- TellGreeter((RequestHeader *)r);
- state->waitForResponse = TRUE;
- state->id = GREET_STATE_EXIT;
- }
- break;
- case GREET_STATE_EXPASSWORD:
- {
- /*
- * Display password expired message.
- */
- RequestExpassword *r;
- Debug("GREET_STATE_EXPASSWORD\n");
- r = (RequestExpassword *)state->request;
- r->hdr.opcode = REQUEST_OP_EXPASSWORD;
- r->hdr.reserved = 0;
- r->hdr.length = sizeof(*r);
- TellGreeter((RequestHeader *)r);
- state->waitForResponse = TRUE;
- state->id = GREET_STATE_USERNAME;
- }
- break;
- case GREET_STATE_BAD_HOSTNAME:
- {
- /*
- * Display password expired message.
- */
- RequestHostname *r;
- Debug("GREET_STATE_BAD_HOSTNAME\n");
- r = (RequestHostname *)state->request;
- r->hdr.opcode = REQUEST_OP_HOSTNAME;
- r->hdr.reserved = 0;
- r->hdr.length = sizeof(*r);
- TellGreeter((RequestHeader *)r);
- state->waitForResponse = TRUE;
- state->id = GREET_STATE_USERNAME;
- }
- break;
- #ifdef SIA
- case GREET_STATE_FORM:
- {
- /*
- * Get arbitrary number of answers.
- */
- Debug("GREET_STATE_FORM\n");
-
- AskGreeter(state->request, (char *)state->response, REQUEST_LIM_MAXLEN);
-
- state->waitForResponse = FALSE;
- state->id = GREET_STATE_USERNAME;
- }
- break;
- #endif /* SIA */
- }
- return(TRUE);
- }
- static void
- TellGreeter(
- RequestHeader *phdr)
- {
- if(-1 == write(request[1], phdr, phdr->length)) {
- perror(strerror(errno));
- }
- }
- static int
- AskGreeter(
- RequestHeader *preqhdr,
- char *buf,
- int blen)
- {
- int count;
- int remainder;
- ResponseHeader *phdr = (ResponseHeader *)buf;
- if (preqhdr) TellGreeter(preqhdr);
- phdr->opcode = REQUEST_OP_NONE;
- count = read(response[0], buf, sizeof(*phdr));
- if (count == sizeof(*phdr))
- {
- /*
- * Calculate amount of data after header.
- */
- remainder = phdr->length - sizeof(*phdr);
- if (remainder > 0)
- {
- /*
- * Read remainder of response.
- */
- count += read(response[0], buf+sizeof(*phdr), remainder);
- }
- }
- #if defined (DEBUG)
- if (debugLevel) PrintResponse(phdr, count);
- #endif /* DEBUG */
- return(count);
- }
- #if defined (DEBUG)
- static void
- PrintResponse(
- ResponseHeader *phdr,
- int count)
- {
- char *opstr = "UNKNOWN";
- if (!count)
- {
- Debug("opcode = (EOF)\n");
- return;
- }
- switch(phdr->opcode)
- {
- case REQUEST_OP_EXIT: opstr = "EXIT"; break;
- case REQUEST_OP_MESSAGE: opstr = "MESSAGE"; break;
- case REQUEST_OP_CHPASS: opstr = "CHPASS"; break;
- case REQUEST_OP_CHALLENGE: opstr = "CHALLENGE"; break;
- case REQUEST_OP_LANG: opstr = "LANG"; break;
- case REQUEST_OP_DEBUG: opstr = "DEBUG"; break;
- }
- Debug("opcode = %d (%s)\n", phdr->opcode, opstr);
- Debug(" reserved = %d\n", phdr->reserved);
- Debug(" length = %d\n", phdr->length);
- switch(phdr->opcode)
- {
- case REQUEST_OP_EXIT: break;
- case REQUEST_OP_LANG:
- Debug(" offLang=%d\n", ((ResponseLang *)phdr)->offLang);
- Debug(" lang='%s'\n",
- ((char *)phdr)+((ResponseLang *)phdr)->offLang);
- break;
- case REQUEST_OP_MESSAGE: break;
- case REQUEST_OP_CHPASS: break;
- case REQUEST_OP_CHALLENGE:
- Debug(" offResponse=%d\n", ((ResponseChallenge *)phdr)->offResponse);
- Debug(" response='%s'\n",
- ((char *)phdr)+((ResponseChallenge *)phdr)->offResponse);
- break;
- case REQUEST_OP_DEBUG:
- Debug(" offString=%d\n", ((ResponseDebug *)phdr)->offString);
- Debug(" string='%s'\n",
- ((char *)phdr)+((ResponseDebug *)phdr)->offString);
- break;
- }
- }
- #endif /* DEBUG */
- #ifdef __KERBEROS
- /***************************************************************************
- *
- * SetTicketFileName
- *
- * generate kerberos ticket file name. Name is returned in the static
- * global variable "krb_ticket_string".
- *
- ***************************************************************************/
- static void
- SetTicketFileName(uid_t uid)
- {
- char *env;
- char lhost[64], *p;
- /*
- * generate ticket file pathname (/tmp/tkt<uid>.<host>) ...
- */
- if (env = (char *)getenv("KRBTKFILE")) {
- (void) strncpy(krb_ticket_string, env, sizeof(krb_ticket_string)-1);
- krb_ticket_string[sizeof(krb_ticket_string)-1] = '\0';
- } else {
- if (gethostname(lhost, sizeof(lhost)) != -1) {
- if (p = index(lhost, '.')) *p = '\0';
- (void)sprintf(krb_ticket_string, "%s%ld.%s", TKT_ROOT, (long)uid, lhost);
- } else {
- /* 32 bits of signed integer will always fit in 11 characters
- (including the sign), so no need to worry about overflow */
- (void) sprintf(krb_ticket_string, "%s%ld", TKT_ROOT, (long)uid);
- }
- }
- }
- #endif /* __KERBEROS */
- #if defined (_AIX) && !defined (_POWER)
- /***************************************************************************
- *
- * session_execve
- *
- * If this is an authenticated process (LOGNAME set), set user's
- * process environment by calling setpenv().
- *
- * If this is not an authenticated process, just call execve()
- *
- ***************************************************************************/
- static int
- session_execve(
- char *path,
- char *argv[],
- char *envp[])
- {
- int rc;
- char *user = getEnv (envp, "LOGNAME");
-
- if (user == NULL)
- {
- rc = execve(path, argv, envp);
- }
- else
- {
- char *usrTag, *sysTag;
- /*
- * Save pointers to tags. The setpenv() function clears the pointers
- * to the tags in userEnviron as a side-effect.
- */
- sysTag = envp[SYS_ENV_TAG];
- usrTag = envp[USR_ENV_TAG];
- /*
- * Set the users process environment. This call execs arvg so it
- * should not return. It it should return, restore the envp tags.
- */
- rc = setpenv(user, PENV_INIT | PENV_ARGV, envp, argv);
- /*
- * Restore pointers to tags.
- */
- envp[SYS_ENV_TAG] = sysTag;
- envp[USR_ENV_TAG] = usrTag;
- }
- return(rc);
- }
- #endif /* _AIX && !_POWER */
- #ifdef SIA
- /* collect the SIA parameters from a window system. */
- static int SiaManageGreeter(
- int timeout,
- int rendition,
- unsigned char *title,
- int num_prompts,
- prompt_t *prompt)
- {
- int i;
- struct {
- RequestMessage greeter_message;
- char msg_buffer[256];
- } greeter_msg_and_buffer;
- RequestForm *request_form;
- switch(rendition)
- {
- case SIAMENUONE:
- case SIAMENUANY:
- case SIAONELINER:
- case SIAFORM:
- if (rendition == SIAFORM && dt_in_sia_ses_authent
- && (num_prompts == 2))
- {
- /* Normal login, Password case */
- Debug ("SIAFORM Normal login, Password case\n");
- while (siaGreeterInfo.state->id != GREET_STATE_TERMINATEGREET
- && siaGreeterInfo.state->id != GREET_STATE_EXIT
- && (siaGreeterInfo.status = ManageGreeter(
- siaGreeterInfo.d, siaGreeterInfo.greet,
- siaGreeterInfo.verify, siaGreeterInfo.state)))
- ;
- if (!siaGreeterInfo.status
- || siaGreeterInfo.state->id == GREET_STATE_EXIT)
- return(SIACOLABORT);
- strncpy((char *)prompt[0].result, siaGreeterInfo.greet->name,
- prompt[0].max_result_length);
- strncpy((char *)prompt[1].result,siaGreeterInfo.greet->password,
- prompt[1].max_result_length);
- }
- else
- {
- char *res_ptr;
- char *pmpt_ptr;
- int req_form_size;
- ResponseForm *response_form;
- switch(rendition)
- {
- case SIAMENUONE:
- Debug("SIAMENUONE num_prompts = %d\n", num_prompts);
- break;
- case SIAMENUANY:
- Debug("SIAMENUANY num_prompts = %d\n", num_prompts);
- break;
- case SIAONELINER:
- Debug("SIAONELINER num_prompts = %d\n", num_prompts);
- break;
- case SIAFORM:
- Debug("SIAFORM num_prompts = %d\n", num_prompts);
- break;
- }
- /* need to display form */
- req_form_size = sizeof(RequestForm)
- + strlen((const char *)title) + 1;
- for (i=0; i<num_prompts; i++)
- req_form_size += strlen((const char *)prompt[i].prompt) + 1;
- request_form = (RequestForm *) alloca(req_form_size);
- siaGreeterInfo.state->id = GREET_STATE_FORM;
- siaGreeterInfo.state->request = (RequestHeader *)request_form;
- /* siaGreeterInfo.state->vf = VF_MESSAGE; */
- request_form->hdr.opcode = REQUEST_OP_FORM;
- request_form->hdr.reserved = 0;
- request_form->hdr.length = req_form_size;
- request_form->num_prompts = num_prompts;
- request_form->rendition = rendition;
- request_form->offTitle = sizeof(RequestForm);
- request_form->offPrompts = sizeof(RequestForm) +
- strlen((const char *)title) + 1;
- strcpy((char *)request_form + request_form->offTitle,
- (const char *)title);
- pmpt_ptr = (char *)request_form + request_form->offPrompts;
- for (i=0; i<num_prompts; i++)
- {
- if (!prompt[i].prompt || prompt[i].prompt[0] == '\0')
- *pmpt_ptr++ = '\0';
- else
- {
- Debug(" prompt[%d]: %s\n", i, prompt[i].prompt);
- strcpy(pmpt_ptr, (const char *)prompt[i].prompt);
- pmpt_ptr += strlen((const char *)prompt[i].prompt);
- }
- request_form->visible[i] =
- (prompt[i].control_flags & SIARESINVIS) ? False : True;
- }
- siaGreeterInfo.status = ManageGreeter(siaGreeterInfo.d,
- siaGreeterInfo.greet,
- siaGreeterInfo.verify,
- siaGreeterInfo.state);
- response_form = (ResponseForm *)siaGreeterInfo.state->response;
- res_ptr = (char *)response_form + response_form->offAnswers;
- for (i = 0; i < response_form->num_answers; i++)
- {
- if (rendition == SIAMENUONE || rendition == SIAMENUANY)
- {
- if (res_ptr[0])
- prompt[i].result = (unsigned char *)1;
- else
- prompt[i].result = NULL;
- }
- else
- {
- strcpy((char *)prompt[0].result, res_ptr);
- }
- res_ptr += strlen(res_ptr) + 1;
- }
- if (!response_form->collect_status)
- siaGreeterInfo.status = FALSE;
- }
- break;
- case SIAINFO:
- case SIAWARNING:
- Debug("SIAINFO or SIAWARNING %s\n", prompt[0].prompt);
- siaGreeterInfo.state->id = GREET_STATE_ERRORMESSAGE;
- siaGreeterInfo.state->request = (RequestHeader *)
- &greeter_msg_and_buffer.greeter_message;
- siaGreeterInfo.state->vf = VF_MESSAGE;
- siaGreeterInfo.state->msg = (char *)prompt[0].prompt;
- siaGreeterInfo.status = ManageGreeter(siaGreeterInfo.d,
- siaGreeterInfo.greet,
- siaGreeterInfo.verify,
- siaGreeterInfo.state);
- break;
- default:
- return(SIACOLABORT);
- break;
- }
- if (!siaGreeterInfo.status)
- return(SIACOLABORT);
- return(SIACOLSUCCESS);
- }
- static CopySiaInfo(SIAENTITY *siaHandle, struct greet_info *greet)
- {
- greet->name = malloc(strlen(siaHandle->name) + 1);
- strcpy (greet->name, siaHandle->name);
- greet->password = malloc(strlen(siaHandle->password) + 1);
- strcpy (greet->password, siaHandle->password);
-
- }
- static void KillGreeter( void )
- {
- if (sia_greeter_pid)
- AbortClient(sia_greeter_pid);
- sia_greeter_pid = 0;
- }
- #endif /* SIA */
|