session.c 85 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* (c) Copyright 1997 The Open Group */
  24. /* *
  25. * (c) Copyright 1993, 1994 Hewlett-Packard Company *
  26. * (c) Copyright 1993, 1994 International Business Machines Corp. *
  27. * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
  28. * (c) Copyright 1993, 1994 Novell, Inc. *
  29. */
  30. /*
  31. * Xdm - display manager daemon
  32. *
  33. * $TOG: session.c /main/21 1998/11/02 14:32:42 mgreess $
  34. *
  35. * Copyright 1988 Massachusetts Institute of Technology
  36. *
  37. * Permission to use, copy, modify, and distribute this software and its
  38. * documentation for any purpose and without fee is hereby granted, provided
  39. * that the above copyright notice appear in all copies and that both that
  40. * copyright notice and this permission notice appear in supporting
  41. * documentation, and that the name of M.I.T. not be used in advertising or
  42. * publicity pertaining to distribution of the software without specific,
  43. * written prior permission. M.I.T. makes no representations about the
  44. * suitability of this software for any purpose. It is provided "as is"
  45. * without express or implied warranty.
  46. *
  47. * Author: Keith Packard, MIT X Consortium
  48. */
  49. /*
  50. * session.c
  51. */
  52. #ifdef _AIX
  53. #ifdef _POWER
  54. #include <stdio.h>
  55. #include <errno.h>
  56. #include <sys/file.h>
  57. #endif /* _POWER */
  58. # include <usersec.h>
  59. #endif /* _AIX */
  60. # include "dm.h"
  61. # include "vgmsg.h"
  62. # include <signal.h>
  63. # include <X11/Xatom.h>
  64. # include <setjmp.h>
  65. #if defined(__FreeBSD__) && OSMAJORVERSION > 8
  66. # include <utmpx.h>
  67. #else
  68. # include <utmp.h>
  69. #endif
  70. #include <unistd.h>
  71. #include <pwd.h>
  72. #include <dirent.h>
  73. #include <limits.h>
  74. #ifdef SIA
  75. #include <sia.h>
  76. #include <siad.h>
  77. #include <X11/Intrinsic.h>
  78. #endif
  79. # include <X11/Xresource.h>
  80. # include "vgproto.h"
  81. # include "sysauth.h"
  82. #ifdef sun
  83. # include "solaris.h"
  84. #endif
  85. #ifdef BLS
  86. # include <sys/security.h>
  87. # include <prot.h>
  88. #endif
  89. #ifdef __KERBEROS
  90. # include <krb.h>
  91. #endif /* __KERBEROS */
  92. #ifdef __PASSWD_ETC
  93. #include "rgy_base.h"
  94. #endif
  95. #ifdef SIA
  96. static SIAENTITY *siaHandle = NULL;
  97. static Boolean dt_in_sia_ses_authent = False;
  98. static struct sia_greeter_info {
  99. struct display *d;
  100. struct greet_info *greet;
  101. struct verify_info *verify;
  102. struct greet_state *state;
  103. int status;
  104. } siaGreeterInfo;
  105. static int SiaManageGreeter(
  106. int timeout,
  107. int rendition,
  108. unsigned char *title,
  109. int num_prompts,
  110. prompt_t *prompt);
  111. static CopySiaInfo(SIAENTITY *siaHandle, struct greet_info *greet);
  112. static void KillGreeter( void );
  113. static int sia_greeter_pid;
  114. static int sia_exit_proc_reg = FALSE;
  115. #endif /* SIA */
  116. #define GREET_STATE_LOGIN 0
  117. #define GREET_STATE_AUTHENTICATE 1
  118. #define GREET_STATE_EXIT 2
  119. #define GREET_STATE_EXPASSWORD 3
  120. #define GREET_STATE_ERRORMESSAGE 4
  121. #define GREET_STATE_LANG 5
  122. #define GREET_STATE_BAD_HOSTNAME 6
  123. #define GREET_STATE_ENTER 7
  124. #define GREET_STATE_TERMINATEGREET 8
  125. #define GREET_STATE_USERNAME 9
  126. #define GREET_STATE_CHALLENGE 10
  127. #define GREET_STATE_FORM 11
  128. #ifndef DEF_SESSION
  129. #define DEF_SESSION CDE_INSTALLATION_TOP "/bin/Xsession"
  130. #endif
  131. #define DOT "."
  132. #define DOTDOT ".."
  133. struct greet_state {
  134. int id; /* state */
  135. int waitForResponse; /* TRUE=wait for response from dtgreet */
  136. RequestHeader *request; /* request buffer */
  137. ResponseHeader *response; /* response buffer */
  138. int authenticated; /* TRUE=user is authenticated */
  139. int vf; /* last return code from Authenticate() */
  140. int loginReset; /* reset flag for LOGIN state */
  141. char *msg; /* message for VF_MESSAGE */
  142. };
  143. char *globalDisplayName;
  144. /***************************************************************************
  145. *
  146. * Local procedure declarations
  147. *
  148. ***************************************************************************/
  149. static int AbortClient( int pid) ;
  150. static void DeleteXloginResources( struct display *d, Display *dpy) ;
  151. int LoadXloginResources( struct display *d) ;
  152. static int ErrorHandler( Display *dpy, XErrorEvent *event) ;
  153. static int IOErrorHandler( Display *dpy) ;
  154. static int ManageGreeter( struct display *d, struct greet_info *greet,
  155. struct verify_info *verify, struct greet_state *state) ;
  156. static void RunGreeter( struct display *d, struct greet_info *greet,
  157. struct verify_info *verify) ;
  158. static void SessionExit( struct display *d, int status) ;
  159. static void SessionPingFailed( struct display *d) ;
  160. static int StartClient(struct verify_info *verify, struct display *d,
  161. int *pidp) ;
  162. static SIGVAL catchAlrm( int arg ) ;
  163. static SIGVAL catchHUP( int arg ) ;
  164. static SIGVAL catchTerm( int arg ) ;
  165. static SIGVAL waitAbort( int arg ) ;
  166. static void SetupDisplay(struct display *d);
  167. static void TellGreeter(RequestHeader *phdr);
  168. static int AskGreeter(RequestHeader *preqhdr, char *b, int blen);
  169. #if defined (DEBUG)
  170. static void PrintResponse(ResponseHeader *phdr, int count);
  171. #endif /* DEBUG */
  172. #if defined (_AIX) && defined (_POWER)
  173. static void release_aix_lic(void);
  174. #endif
  175. #if defined (_AIX) && !defined (_POWER)
  176. static int session_execve(char *path, char *argv[], char *envp[]);
  177. #else
  178. #define session_execve(A,B,C) execve(A,B,C)
  179. #endif
  180. # ifdef __KERBEROS
  181. static void SetTicketFileName(uid_t uid);
  182. # endif /* __KERBEROS */
  183. static void LoadAltDtsResources( struct display *d);
  184. char * _ExpandLang(char *string, char *lang);
  185. /***************************************************************************
  186. *
  187. * Global variables
  188. *
  189. ***************************************************************************/
  190. static int clientPid;
  191. static struct greet_info greet;
  192. static struct verify_info verify;
  193. static char *defaultLanguage = NULL;
  194. static jmp_buf abortSession;
  195. #ifdef BLS
  196. static char *sensitivityLevel;
  197. #endif
  198. #ifdef __KERBEROS
  199. static char krb_ticket_string[MAXPATHLEN];
  200. #endif /* __KERBEROS */
  201. XrmDatabase XresourceDB;
  202. XrmDatabase XDB;
  203. static SIGVAL
  204. catchTerm( int arg )
  205. {
  206. longjmp (abortSession, 1);
  207. }
  208. static jmp_buf pingTime;
  209. static SIGVAL
  210. catchAlrm( int arg )
  211. {
  212. longjmp (pingTime, 1);
  213. }
  214. #if defined(__STDC__)
  215. static int
  216. FileNameCompare (const char *a, const char *b)
  217. #else
  218. static int
  219. FileNameCompare (char *a, char *b)
  220. #endif
  221. {
  222. return strcoll (*(char **)a, *(char **)b);
  223. }
  224. static void
  225. SessionPingFailed( struct display *d )
  226. {
  227. if (clientPid > 1)
  228. {
  229. AbortClient (clientPid);
  230. source (&verify, d->reset);
  231. #if defined (PAM) || defined(SUNAUTH)
  232. {
  233. char* user = getEnv (verify.userEnviron, "USER");
  234. char* ttyLine = d->gettyLine;
  235. #ifdef DEF_NETWORK_DEV
  236. /*
  237. * If location is not local (remote XDMCP dtlogin) and
  238. * remote accouting is enabled (networkDev start with /dev/...)
  239. * Set tty line name to match network device for accouting.
  240. * Unless the resource was specifically set, default is value
  241. * of DEF_NETWORK_DEV define (/dev/dtremote)
  242. */
  243. if ( d->displayType.location != Local &&
  244. networkDev && !strncmp(networkDev,"/dev/",5)) {
  245. ttyLine = networkDev+5;
  246. }
  247. #endif
  248. # ifdef PAM
  249. PamAccounting( verify.argv[0], d->name, d->utmpId, user,
  250. ttyLine, clientPid, ACCOUNTING, NULL);
  251. # else
  252. solaris_accounting( verify.argv[0], d->name, d->utmpId, user,
  253. ttyLine, clientPid, ACCOUNTING, NULL);
  254. # endif
  255. # ifdef sun
  256. solaris_resetdevperm(ttyLine);
  257. # endif
  258. }
  259. #endif
  260. }
  261. SessionExit (d, RESERVER_DISPLAY);
  262. }
  263. /*
  264. * We need our own error handlers because we can't be sure what exit code Xlib
  265. * will use, and our Xlib does exit(1) which matches REMANAGE_DISPLAY, which
  266. * can cause a race condition leaving the display wedged. We need to use
  267. * RESERVER_DISPLAY for IO errors, to ensure that the manager waits for the
  268. * server to terminate. For other X errors, we should give up.
  269. */
  270. static int
  271. IOErrorHandler( Display *dpy )
  272. {
  273. const char *s = strerror(errno);
  274. LogError(ReadCatalog(
  275. MC_LOG_SET,MC_LOG_FATAL_IO,MC_DEF_LOG_FATAL_IO),
  276. errno,s);
  277. exit(RESERVER_DISPLAY);
  278. return 0;
  279. }
  280. static int
  281. ErrorHandler( Display *dpy, XErrorEvent *event )
  282. {
  283. LogError(ReadCatalog(MC_LOG_SET,MC_LOG_X_ERR,MC_DEF_LOG_X_ERR));
  284. if (XmuPrintDefaultErrorMessage (dpy, event, stderr) == 0) return 0;
  285. exit(UNMANAGE_DISPLAY);
  286. }
  287. Display *dpy;
  288. void
  289. ManageSession( struct display *d )
  290. {
  291. int pid;
  292. Window root;
  293. /* Display *dpy; */
  294. #ifdef BYPASSLOGIN
  295. char *BypassUsername;
  296. char *BypassLogin();
  297. #endif /* BYPASSLOGIN */
  298. Debug ("ManageSession():\n");
  299. /***********************************/
  300. /** remember the default language **/
  301. /***********************************/
  302. if (defaultLanguage == NULL) {
  303. if ( (d->language != NULL) && (strlen(d->language) > 0) ) {
  304. defaultLanguage = strdup(d->language);
  305. } else {
  306. defaultLanguage = "C";
  307. }
  308. }
  309. #ifdef BYPASSLOGIN
  310. d->bypassLogin = 0;
  311. if ((BypassUsername = BypassLogin(d->name)) != NULL) {
  312. d->bypassLogin = 1;
  313. Debug("Login bypassed, running as %s\n",BypassUsername);
  314. greet.name = BypassUsername;
  315. if (!Verify (d, &greet, &verify)) {
  316. Debug ("Login bypass verify failed!\n");
  317. SessionExit (d, GREETLESS_FAILED);
  318. }
  319. Debug("Login bypass verify succeded!\n");
  320. } else
  321. #endif /* BYPASSLOGIN */
  322. {
  323. int i;
  324. (void)XSetIOErrorHandler(IOErrorHandler);
  325. (void)XSetErrorHandler(ErrorHandler);
  326. SetTitle(d->name, (char *) 0);
  327. /*
  328. * set root background to black...
  329. */
  330. dpy = XOpenDisplay(d->name);
  331. for (i = ScreenCount(dpy) - 1; i >= 0; i--)
  332. {
  333. Window tmproot = RootWindow(dpy, i);
  334. if (i == DefaultScreen(dpy))
  335. root = tmproot;
  336. XSetWindowBackground(dpy, tmproot, BlackPixel(dpy, i));
  337. XClearWindow(dpy, tmproot);
  338. }
  339. XFlush(dpy);
  340. /*
  341. ** Step 5:
  342. ** Invoke Greet program, wait for completion.
  343. ** If this routine returns, the user will have been
  344. ** verified, otherwise the routine will exit inter-
  345. ** nally with an appropriate exit code for the master
  346. ** Dtlogin process.
  347. */
  348. greet.name = greet.string = NULL;
  349. while (greet.name == NULL) {
  350. SetHourGlassCursor(dpy, root);
  351. LoadXloginResources (d);
  352. SetupDisplay(d);
  353. ApplyFontPathMods(d, dpy);
  354. (void)XSetErrorHandler(ErrorHandler);
  355. RunGreeter(d, &greet, &verify);
  356. DeleteXloginResources (d, dpy);
  357. }
  358. XSetInputFocus(dpy, root, RevertToNone, CurrentTime);
  359. XCloseDisplay(dpy);
  360. }
  361. #ifdef __KERBEROS
  362. /*
  363. * Generate Kerberos ticket file name. Put in system and user
  364. * environments...
  365. */
  366. if ( IsVerifyName(VN_KRB)) {
  367. SetTicketFileName(verify.uid);
  368. krb_set_tkt_string(krb_ticket_string);
  369. verify.systemEnviron = setEnv (verify.systemEnviron,
  370. "KRBTKFILE",
  371. krb_ticket_string);
  372. verify.userEnviron = setEnv (verify.userEnviron,
  373. "KRBTKFILE",
  374. krb_ticket_string);
  375. }
  376. #endif /* __KERBEROS */
  377. /* set LOCATION env var */
  378. if(d->displayType.location == Local) {
  379. verify.systemEnviron = setEnv (verify.systemEnviron,
  380. LOCATION,
  381. "local");
  382. /* ITE is needed only for Local displays */
  383. /* set ITE env var */
  384. if(d->gettyLine)
  385. verify.systemEnviron = setEnv (verify.systemEnviron,
  386. "ITE",
  387. d->gettyLine);
  388. }
  389. else
  390. verify.systemEnviron = setEnv (verify.systemEnviron,
  391. LOCATION,
  392. "remote");
  393. {
  394. struct passwd *pwd;
  395. char gid[25];
  396. sprintf(gid,"%ld",(long)getgid());
  397. /* set user group id (USER_GID) env var */
  398. verify.systemEnviron = setEnv (verify.systemEnviron,
  399. "USER_GID",
  400. gid);
  401. /* set root group id (ROOT_GID) env var */
  402. pwd = getpwnam("root");
  403. if(pwd) {
  404. sprintf(gid,"%ld",(long)pwd->pw_gid);
  405. verify.systemEnviron = setEnv (verify.systemEnviron,
  406. "ROOT_GID",
  407. gid);
  408. }
  409. }
  410. /*
  411. * Run system-wide initialization file
  412. */
  413. if (source (&verify, d->startup) != 0)
  414. {
  415. Debug ("Startup program %s exited with non-zero status\n",
  416. d->startup);
  417. SessionExit (d, OBEYSESS_DISPLAY);
  418. }
  419. #ifdef sun
  420. if ( solaris_setdevperm(d->gettyLine, verify.uid, verify.gid) == 0 ) {
  421. SessionExit (d, OBEYSESS_DISPLAY);
  422. }
  423. #endif
  424. clientPid = 0;
  425. if (!setjmp (abortSession)) {
  426. signal (SIGTERM, catchTerm);
  427. /*
  428. * Start the clients, changing uid/groups
  429. * setting up environment and running the session
  430. */
  431. if (StartClient (&verify, d, &clientPid)) {
  432. Debug ("Client started\n");
  433. /*
  434. * We've changed dtlogin to pass HUP's down to the children
  435. * so ignore any HUP's once the client has started.
  436. */
  437. signal(SIGHUP, SIG_IGN);
  438. /*
  439. * Wait for session to end,
  440. */
  441. for (;;) {
  442. if (d->pingInterval)
  443. {
  444. if (!setjmp (pingTime))
  445. {
  446. signal (SIGALRM, catchAlrm);
  447. alarm (d->pingInterval * 60);
  448. pid = wait ((waitType *) 0);
  449. alarm (0);
  450. }
  451. else
  452. {
  453. alarm (0);
  454. if (!PingServer (d, (Display *) NULL))
  455. SessionPingFailed (d);
  456. }
  457. }
  458. else
  459. {
  460. pid = wait ((waitType *) 0);
  461. }
  462. if (pid == clientPid)
  463. break;
  464. }
  465. /*
  466. * We've changed dtlogin to pass HUP's down to the children
  467. * so ignore any HUP's once the client has started.
  468. */
  469. signal(SIGHUP, SIG_DFL);
  470. } else {
  471. LogError(ReadCatalog(
  472. MC_LOG_SET,MC_LOG_FAIL_START,MC_DEF_LOG_FAIL_START));
  473. }
  474. } else {
  475. /*
  476. * when terminating the session, nuke
  477. * the child and then run the reset script
  478. */
  479. AbortClient (clientPid);
  480. }
  481. /*
  482. * on foreign displays without XDMCP, send a SIGTERM to the process
  483. * group of the session manager. This augments the "resetServer()"
  484. * routine and helps get all clients killed. It is possible for a client
  485. * to have a connection to the server, but not have a window.
  486. */
  487. if (d->displayType.location == Foreign &&
  488. d->displayType.origin != FromXDMCP )
  489. AbortClient(clientPid);
  490. #ifdef __KERBEROS
  491. /*
  492. * remove ticket file...
  493. */
  494. if ( IsVerifyName(VN_KRB) ) {
  495. dest_tkt();
  496. }
  497. #endif /* __KERBEROS */
  498. /*
  499. * run system-wide reset file
  500. */
  501. Debug ("Source reset program %s\n", d->reset);
  502. source (&verify, d->reset);
  503. #if defined(PAM) || defined(SUNAUTH)
  504. {
  505. char* user = getEnv (verify.userEnviron, "USER");
  506. char* ttyLine = d->gettyLine;
  507. # ifdef DEF_NETWORK_DEV
  508. /*
  509. * If location is not local (remote XDMCP dtlogin) and
  510. * remote accouting is enabled (networkDev start with /dev/...)
  511. * Set tty line name to match network device for accouting.
  512. * Unless the resource was specifically set, default is value
  513. * of DEF_NETWORK_DEV define (/dev/dtremote)
  514. */
  515. if ( d->displayType.location != Local &&
  516. networkDev && !strncmp(networkDev,"/dev/",5)) {
  517. ttyLine = networkDev+5;
  518. }
  519. # endif
  520. # ifdef PAM
  521. PamAccounting( verify.argv[0], d->name, d->utmpId, user,
  522. ttyLine, clientPid, ACCOUNTING, NULL);
  523. # else
  524. solaris_accounting( verify.argv[0], d->name, d->utmpId, user,
  525. ttyLine, clientPid, ACCOUNTING, NULL);
  526. # endif
  527. # ifdef sun
  528. solaris_resetdevperm(ttyLine);
  529. # endif
  530. }
  531. #endif
  532. SessionExit (d, OBEYSESS_DISPLAY);
  533. }
  534. int
  535. LoadXloginResources( struct display *d )
  536. {
  537. char cmd[1024];
  538. char *authority="";
  539. char *auth_key="";
  540. char *resources = NULL;
  541. char *p;
  542. char tmpname[32];
  543. if (d->resources && d->resources[0]) {
  544. resources = _ExpandLang(d->resources, d->language);
  545. if (access (resources, R_OK) != 0) {
  546. /** fallback to the C locale for resources **/
  547. Debug("LoadXloginResources - cant access %s\n", resources);
  548. Debug("\t %s. Falling back to C.\n", strerror(errno));
  549. free(resources);
  550. resources = _ExpandLang(d->resources, "C");
  551. if (access (resources, R_OK) != 0) {
  552. /** can't find a resource file, so bail **/
  553. Debug("LoadXloginResources - cant access %s.\n", resources);
  554. Debug("\t %s. Unable to find resource file.\n",
  555. strerror(errno));
  556. free(resources);
  557. return(-1);
  558. }
  559. }
  560. if (d->authFile && strlen(d->authFile) > 0 ) {
  561. authority = d->authFile;
  562. auth_key = "XAUTHORITY=";
  563. }
  564. Debug("LoadXloginResources - loading resource db from %s\n", resources);
  565. if((XresourceDB = XrmGetFileDatabase(resources)) == NULL)
  566. Debug("LoadXloginResources - Loading resource db from %s failed\n",
  567. resources);
  568. LoadAltDtsResources(d);
  569. strcpy(tmpname,"/var/dt/dtlogin_XXXXXX");
  570. (void) mktemp(tmpname);
  571. XrmPutFileDatabase(XresourceDB, tmpname);
  572. sprintf (cmd, "%s%s %s -display %s -load %s",
  573. auth_key, authority, d->xrdb, d->name, tmpname);
  574. Debug ("Loading resource file: %s\n", cmd);
  575. if(-1 == system (cmd)) {
  576. Debug ("system() failed on cmd '%s'\n", cmd);
  577. return -1;
  578. }
  579. if (debugLevel <= 10)
  580. if (unlink (tmpname) == -1)
  581. Debug ("unlink() on %s failed\n", tmpname);
  582. }
  583. if (resources) free (resources);
  584. return (0);
  585. }
  586. /***************************************************************************
  587. *
  588. * LoadAltDtsResources
  589. *
  590. *
  591. * set up alternate desktop resources..
  592. *
  593. ***************************************************************************/
  594. static void
  595. LoadAltDtsResources(struct display *d)
  596. {
  597. DIR *dirp;
  598. struct dirent *dp;
  599. char dirname[2][MAXPATHLEN];
  600. char res_file[MAXPATHLEN];
  601. char *rmtype; /* for XrmGetResource() */
  602. XrmValue rmvalue; /* for XrmGetResource() */
  603. char buf[MAXPATHLEN];
  604. char tempbuf[MAXPATHLEN];
  605. XrmDatabase defDb;
  606. XrmDatabase userDb;
  607. char altdtres[MAXPATHLEN];
  608. char Altdtres[MAXPATHLEN];
  609. int i = 0;
  610. int j = 0;
  611. char *resources = NULL;
  612. int file_count = 0;
  613. int num_allocated = 0;
  614. char **file_list = NULL;
  615. int list_incr = 10;
  616. if ( XrmGetResource(XresourceDB,
  617. "Dtlogin*altDts", "Dtlogin*AltDts",
  618. &rmtype, &rmvalue ) ) {
  619. snprintf(tempbuf, sizeof(tempbuf), "%s", rmvalue.addr);
  620. i = atoi(tempbuf);
  621. }
  622. strcpy(dirname[0],CDE_INSTALLATION_TOP "/config/%L/Xresources.d/");
  623. strcpy(dirname[1],CDE_CONFIGURATION_TOP "/config/%L/Xresources.d/");
  624. for(j = 0; j < 2 ; ++j)
  625. {
  626. resources = _ExpandLang(dirname[j], d->language);
  627. if (access (resources, R_OK) != 0)
  628. {
  629. Debug("LoadAltDtsResources- cant access %s.\n", resources);
  630. Debug("\t %s. Falling back to C.\n", strerror(errno));
  631. free (resources);
  632. resources = NULL;
  633. resources = _ExpandLang(dirname[j], "C");
  634. if (access (resources, R_OK) != 0)
  635. {
  636. Debug("LoadAltDtsResources- cant access %s.\n", resources);
  637. Debug("\t %s.\n", strerror(errno));
  638. }
  639. else
  640. snprintf(dirname[j], sizeof(dirname[j]), "%s", resources);
  641. }
  642. else {
  643. snprintf(dirname[j], sizeof(dirname[j]), "%s", resources);
  644. Debug("LoadAltDtsResources- found resource dir %s\n", dirname[j]);
  645. }
  646. free (resources);
  647. resources = NULL;
  648. }
  649. /*
  650. * Create a list of the alt DT files
  651. *
  652. * NOTE - an assumption made here is that files in /etc/dt
  653. * should take precedence over files in /usr/dt. This precedence
  654. * is maintained during the sort becase /etc/dt will come before
  655. * /usr/dt
  656. */
  657. for(j = 0; j < 2 ; ++j) {
  658. if((dirp = opendir(dirname[j])) != NULL) {
  659. while((dp = readdir(dirp)) != NULL) {
  660. if ((strcmp(dp->d_name, DOT) != 0) &&
  661. (strcmp(dp->d_name, DOTDOT) != 0)) {
  662. sprintf (res_file, "%s%s", dirname[j],dp->d_name);
  663. if ((access (res_file, R_OK)) != 0)
  664. {
  665. Debug("LoadAltDtsResources- cant access %s.\n",
  666. resources);
  667. Debug("\t %s.\n", strerror(errno));
  668. continue;
  669. }
  670. if (file_count == 0) {
  671. file_list = malloc (list_incr * sizeof(char *));
  672. num_allocated += list_incr;
  673. }
  674. if (file_count + 1 > num_allocated) {
  675. num_allocated += list_incr;
  676. file_list = realloc (file_list,
  677. num_allocated * sizeof(char *));
  678. }
  679. file_list[file_count] = strdup (res_file);
  680. file_count++;
  681. }
  682. }
  683. closedir(dirp);
  684. }
  685. }
  686. if (file_count > 0)
  687. qsort (file_list, file_count, sizeof (char *), FileNameCompare);
  688. for (j = 0; j < file_count ; j++) {
  689. userDb = XrmGetFileDatabase(file_list[j]);
  690. XrmMergeDatabases(userDb,&XresourceDB);
  691. if ( XrmGetResource(XresourceDB, "Dtlogin*altDtsIncrement",
  692. "Dtlogin*AltDtsIncrement", &rmtype, &rmvalue ) ) {
  693. /*
  694. * remove the trailing spaces
  695. */
  696. if(strchr(rmvalue.addr,' '))
  697. snprintf(tempbuf, sizeof(tempbuf), "%s", strtok(rmvalue.addr," "));
  698. else
  699. snprintf(tempbuf, sizeof(tempbuf), "%s", rmvalue.addr);
  700. if ((strcmp(tempbuf, "True") == 0) ||
  701. (strcmp(tempbuf, "TRUE") == 0)) {
  702. if ( XrmGetResource(XresourceDB,
  703. "Dtlogin*altDtKey", "Dtlogin*AltDtKey",
  704. &rmtype, &rmvalue ) ) {
  705. ++i;
  706. sprintf(altdtres,"Dtlogin*altDtKey%d",i);
  707. XrmPutStringResource(&XresourceDB, altdtres, rmvalue.addr);
  708. }
  709. else
  710. continue;
  711. if ( XrmGetResource(XresourceDB,
  712. "Dtlogin*altDtName", "Dtlogin*AltDtName",
  713. &rmtype, &rmvalue ) ) {
  714. sprintf(altdtres,"Dtlogin*altDtName%d",i);
  715. XrmPutStringResource(&XresourceDB, altdtres, rmvalue.addr);
  716. }
  717. if ( XrmGetResource(XresourceDB,
  718. "Dtlogin*altDtStart", "Dtlogin*AltDtStart",
  719. &rmtype, &rmvalue ) ) {
  720. sprintf(altdtres,"Dtlogin*altDtStart%d",i);
  721. XrmPutStringResource(&XresourceDB, altdtres, rmvalue.addr);
  722. }
  723. if ( XrmGetResource(XresourceDB,
  724. "Dtlogin*altDtLogo", "Dtlogin*AltDtLogo",
  725. &rmtype, &rmvalue ) ) {
  726. sprintf(altdtres,"Dtlogin*altDtLogo%d",i);
  727. XrmPutStringResource(&XresourceDB, altdtres, rmvalue.addr);
  728. }
  729. }
  730. }
  731. }
  732. sprintf(tempbuf,"%d",i);
  733. XrmPutStringResource(&XresourceDB, "Dtlogin*altDts", tempbuf);
  734. if (file_count > 0) {
  735. for (i = 0; i < file_count; i++) {
  736. Debug ("Loading resource file: %s\n", file_list[i]);
  737. free (file_list[i]);
  738. }
  739. free (file_list);
  740. }
  741. }
  742. /******************
  743. *
  744. * Function Name: _ExpandLang
  745. *
  746. * Description:
  747. *
  748. * This function takes the string "string", searches for occurences of
  749. * "%L" in the string and if found, the "%L" is substituted with
  750. * the value of the $LANG environment variable.
  751. *
  752. * If $LANG is not defined, the %L is replace with NULL.
  753. *
  754. * Note:
  755. *
  756. * _ExpandLang() is based on the DtSvc _DtExpandLang() static routine.
  757. *
  758. * Synopsis:
  759. *
  760. * ret_string = _ExpandLang (string);
  761. *
  762. * char *ret_string; Returns NULL if "string" is NULL or it points
  763. * to the expanded string.
  764. *
  765. * char *string; The first part of the pathname. Typically
  766. * the directory containing the item of interest.
  767. *
  768. * Note: The caller is responsible for free'ing the returned string.
  769. *
  770. ******************/
  771. char *
  772. _ExpandLang(
  773. char *string,
  774. char *lang )
  775. {
  776. char *tmp;
  777. char *pch;
  778. char *trail;
  779. int n = 0;
  780. int lang_len = 0;
  781. int tmp_len;
  782. int i = 0;
  783. if (string == NULL)
  784. return (NULL);
  785. /*
  786. * Count the number of expansions that will occur.
  787. */
  788. for (n = 0, pch = string ; pch != NULL ; ) {
  789. if ((pch = strchr (pch, '%')) != NULL) {
  790. n++;
  791. pch++;
  792. }
  793. }
  794. if (n == 0)
  795. return (strdup(string));
  796. /*
  797. * We should really be calling setlocale to determine the "default"
  798. * locale but setlocale's return value is not standardized across
  799. * the various vendor platforms nor is it consistent within differnt
  800. * revs of individual OS's. (e.g. its changing between HP-UX 9.0 and
  801. * HP-UX 10.0). The "right" call would be the following line:
  802. *
  803. * if ((lang = getenv ("LANG")) || (lang = setlocale(LC_C_TYPE,NULL)))
  804. *
  805. * Here we hard code the default to "C" instead of leaving it NULL.
  806. */
  807. if (lang || (lang = getenv ("LANG")) || (lang = "C"))
  808. lang_len = strlen (lang);
  809. /*
  810. * Create the space needed.
  811. */
  812. tmp_len = strlen (string) + (n * lang_len) + n + 1;
  813. tmp = (char *) malloc (tmp_len);
  814. for (i = 0; i < tmp_len; tmp[i] = '\0', i++);
  815. pch = string;
  816. while (pch != NULL) {
  817. trail = pch;
  818. if ((pch = strchr (pch, '%')) != NULL) {
  819. pch++;
  820. if (pch == NULL) {
  821. (void) strncat (tmp, trail, ((pch - 1) - trail) + 1);
  822. }
  823. else if ((pch != NULL) && *pch == 'L') {
  824. if (lang_len == 0) {
  825. if (((pch - trail) >=2) && (*(pch-2) == '/'))
  826. /*
  827. * Remove the "/" as well as the "%L".
  828. */
  829. (void) strncat (tmp, trail, (pch - trail) - 2);
  830. else
  831. (void) strncat (tmp, trail, (pch - trail) - 1);
  832. }
  833. else {
  834. /*
  835. * Remove the "%L" and then append the LANG.
  836. */
  837. (void) strncat (tmp, trail, (pch - trail) - 1);
  838. (void) strcat (tmp, lang);
  839. }
  840. }
  841. else {
  842. (void) strncat (tmp, trail, (pch - trail) + 1);
  843. }
  844. if (pch != NULL)
  845. pch++;
  846. }
  847. else {
  848. /*
  849. * A '%' was not found.
  850. */
  851. (void) strcat (tmp, trail);
  852. }
  853. }
  854. return (tmp);
  855. }
  856. static void
  857. SetupDisplay (struct display *d)
  858. {
  859. char **env = 0, **crt_systemEnviron;
  860. if (d->setup && d->setup[0] && (access(d->setup, R_OK ) == 0))
  861. {
  862. crt_systemEnviron = verify.systemEnviron;
  863. env = systemEnv (d, (char *) 0, (char *) 0);
  864. if (d->authFile && strlen(d->authFile) > 0 )
  865. env = setEnv( env, "XAUTHORITY", d->authFile );
  866. if(d->displayType.location == Local)
  867. env = setEnv (env, LOCATION, "local");
  868. else
  869. env = setEnv (env, LOCATION, "remote");
  870. verify.systemEnviron = env;
  871. source (&verify, d->setup);
  872. verify.systemEnviron = crt_systemEnviron;
  873. freeEnv (env);
  874. }
  875. }
  876. /*ARGSUSED*/
  877. static void
  878. DeleteXloginResources( struct display *d, Display *dpy )
  879. {
  880. XDeleteProperty(dpy, RootWindow (dpy, 0), XA_RESOURCE_MANAGER);
  881. }
  882. #if 0 /* dead code: transferred to Dtgreet */
  883. static jmp_buf syncJump;
  884. static SIGVAL
  885. syncTimeout ()
  886. {
  887. longjmp (syncJump, 1);
  888. }
  889. SecureDisplay (d, dpy)
  890. struct display *d;
  891. Display *dpy;
  892. {
  893. Debug ("SecureDisplay():\n");
  894. signal (SIGALRM, syncTimeout);
  895. if (setjmp (syncJump)) {
  896. LogError(ReadCatalog(MC_LOG_SET,MC_LOG_NO_SECDPY,MC_DEF_LOG_NO_SECDPY),
  897. d->name);
  898. SessionExit (d, RESERVER_DISPLAY);
  899. }
  900. alarm ((unsigned) d->grabTimeout);
  901. Debug ("Before XGrabServer()\n");
  902. XGrabServer (dpy);
  903. if (XGrabKeyboard (dpy, DefaultRootWindow (dpy), True, GrabModeAsync,
  904. GrabModeAsync, CurrentTime) != GrabSuccess)
  905. {
  906. alarm (0);
  907. signal (SIGALRM, SIG_DFL);
  908. LogError(ReadCatalog(MC_LOG_SET,MC_LOG_NO_SECKEY,MC_DEF_LOG_NO_SECKEY),
  909. d->name);
  910. SessionExit (d, RESERVER_DISPLAY);
  911. }
  912. Debug ("XGrabKeyboard() succeeded\n");
  913. alarm (0);
  914. signal (SIGALRM, SIG_DFL);
  915. pseudoReset (dpy);
  916. if (!d->grabServer)
  917. {
  918. XUngrabServer (dpy);
  919. XSync (dpy, 0);
  920. }
  921. Debug ("Done secure %s\n", d->name);
  922. }
  923. UnsecureDisplay (d, dpy)
  924. struct display *d;
  925. Display *dpy;
  926. {
  927. Debug ("Unsecure display %s\n", d->name);
  928. if (d->grabServer)
  929. XUngrabServer (dpy);
  930. XSync (dpy, 0);
  931. }
  932. #endif
  933. #ifdef _AIX
  934. #ifdef _POWER
  935. static void
  936. release_aix_lic(void)
  937. {
  938. /*
  939. * Release AIX iFOR/LS license (if any)
  940. */
  941. int fd;
  942. struct pipeinfo {
  943. int request_type;
  944. pid_t login_pid;
  945. } release_me;
  946. release_me.request_type = -1;
  947. release_me.login_pid = getpid();
  948. if ((fd = open("/etc/security/monitord_pipe", O_RDWR, 0600)) >= 0)
  949. {
  950. write(fd, &release_me, sizeof(release_me));
  951. close(fd);
  952. }
  953. Debug("release message to monitord: %s\n", (fd >= 0) ? "OK" : "failed");
  954. }
  955. #endif /* _POWER */
  956. #endif /* _AIX */
  957. static void
  958. SessionExit( struct display *d, int status )
  959. {
  960. #ifdef _AIX
  961. #ifdef _POWER
  962. release_aix_lic();
  963. #endif /* _POWER */
  964. #endif /* _AIX */
  965. /* make sure the server gets reset after the session is over */
  966. if (d->serverPid >= 2) {
  967. Debug("Resetting server: pid %d signal %d\n",
  968. d->serverPid, d->resetSignal);
  969. if (d->terminateServer == 0 && d->resetSignal)
  970. kill (d->serverPid, d->resetSignal);
  971. }
  972. else
  973. ResetServer (d);
  974. Debug("Exiting Session with status: %d\n", status);
  975. exit (status);
  976. }
  977. static int
  978. StartClient( struct verify_info *verify, struct display *d, int *pidp )
  979. {
  980. char **f, *home;
  981. char currentdir[PATH_MAX+1];
  982. char *failsafeArgv[20];
  983. char *user; /* users name */
  984. char *lang, *font; /* failsafe LANG and font */
  985. int pid;
  986. int failsafe = FALSE; /* do we run the failsafe session? */
  987. int password = FALSE; /* do we run /bin/passwd? */
  988. int i;
  989. FILE *lastsession;
  990. char lastsessfile[MAXPATHLEN];
  991. #ifdef BLS
  992. struct pr_passwd *b1_pwd;
  993. #endif
  994. #ifdef __AFS
  995. #define NOPAG 0xffffffff
  996. long pagval, j;
  997. long ngroups, groups[NGROUPS];
  998. #endif /* __AFS */
  999. waitType status;
  1000. if (verify->argv) {
  1001. Debug ("StartSession %s: ", verify->argv[0]);
  1002. for (f = verify->argv; *f; f++) {
  1003. Debug ("%s ", *f);
  1004. if ( strcmp(*f, "failsafe") == 0) failsafe = TRUE;
  1005. if ( strcmp(*f, "password") == 0) failsafe = password = TRUE;
  1006. }
  1007. Debug ("; ");
  1008. }
  1009. if (verify->userEnviron) {
  1010. for (f = verify->userEnviron; *f; f++)
  1011. Debug ("%s ", *f);
  1012. Debug ("\n");
  1013. }
  1014. user = getEnv (verify->userEnviron, "USER");
  1015. switch (pid = fork ()) {
  1016. case 0:
  1017. #ifdef SIA
  1018. /* Force a failsafe session if we can't touch the home directory
  1019. * SIA has already attempted to chdir to HOME, and the current dir
  1020. * will be set to / if it failed. We just check to see if the HOME
  1021. * path is our current directory or not.
  1022. */
  1023. home = getEnv (verify->userEnviron, "HOME");
  1024. getcwd(currentdir, PATH_MAX+1);
  1025. Debug("Current directory is: %s\n", currentdir);
  1026. #if 0
  1027. /*
  1028. * CDExc17917
  1029. * The following little check doesn't really work. For example,
  1030. * here at the XC, NIS reports my home directory as
  1031. * "/site/guests/montyb" while getcwd comes up with
  1032. * "/net/nexus/site/guests/montyb".
  1033. */
  1034. if (strcmp(home, currentdir)) {
  1035. Debug("Can't access home directory, setting failsafe to TRUE\n");
  1036. failsafe = TRUE;
  1037. LogError (ReadCatalog(
  1038. MC_LOG_SET,MC_LOG_NO_HMDIR,MC_DEF_LOG_NO_HMDIR),
  1039. home, getEnv (verify->userEnviron, "USER"));
  1040. verify->userEnviron = setEnv(verify->userEnviron, "HOME", "/");
  1041. }
  1042. #endif
  1043. #endif /* SIA */
  1044. CleanUpChild ();
  1045. /*
  1046. * do process accounting...
  1047. */
  1048. #if defined(PAM) || defined(SUNAUTH)
  1049. {
  1050. char* ttyLine = d->gettyLine;
  1051. # ifdef DEF_NETWORK_DEV
  1052. /*
  1053. * If location is not local (remote XDMCP dtlogin) and
  1054. * remote accouting is enabled (networkDev start with /dev/...)
  1055. * Set tty line name to match network device for accouting.
  1056. * Unless the resource was specifically set, default is value
  1057. * of DEF_NETWORK_DEV define (/dev/dtremote)
  1058. */
  1059. if ( d->displayType.location != Local &&
  1060. networkDev && !strncmp(networkDev,"/dev/",5)) {
  1061. ttyLine = networkDev+5;
  1062. }
  1063. # endif
  1064. # ifdef PAM
  1065. PamAccounting(verify->argv[0], d->name, d->utmpId, user,
  1066. ttyLine, getpid(), USER_PROCESS, NULL);
  1067. # else
  1068. solaris_accounting(verify->argv[0], d->name, d->utmpId, user,
  1069. ttyLine, getpid(), USER_PROCESS, NULL);
  1070. # endif
  1071. }
  1072. #endif
  1073. #if !defined(sun) && !defined(CSRG_BASED)
  1074. Account(d, user, NULL, getpid(), USER_PROCESS, status);
  1075. #endif
  1076. #ifdef AIXV3
  1077. /*
  1078. * In _AIX _POWER, the PENV_NOEXEC flag was added. This tells
  1079. * setpenv() to set up the user's process environment and return
  1080. * without execing. This allows us to set up the process environment
  1081. * and proceed to the execute() call as do the other platforms.
  1082. *
  1083. * Unfortunately, for AIXV3, the PENV_NOEXEC does not exist, so
  1084. * we have to pospone the setpenv() to the actual execute().
  1085. */
  1086. /*
  1087. * These defines are the tag locations in userEnviron.
  1088. * IMPORTANT: changes to the locations of these tags in verify.c
  1089. * must be reflected here by adjusting SYS_ENV_TAG or USR_ENV_TAG.
  1090. */
  1091. #define SYS_ENV_TAG 0
  1092. #define USR_ENV_TAG 3
  1093. /*
  1094. * Set the user's credentials: uid, gid, groups,
  1095. * audit classes, user limits, and umask.
  1096. * RK 09.13.93
  1097. */
  1098. if (setpcred(user, NULL) == -1)
  1099. {
  1100. Debug("Can't set User's Credentials (user=%s)\n",user);
  1101. return (0);
  1102. }
  1103. #ifdef _POWER
  1104. {
  1105. char *usrTag, *sysTag;
  1106. extern char **newenv;
  1107. /*
  1108. * Save pointers to tags. The setpenv() function clears the pointers
  1109. * to the tags in userEnviron as a side-effect.
  1110. */
  1111. sysTag = verify->userEnviron[SYS_ENV_TAG];
  1112. usrTag = verify->userEnviron[USR_ENV_TAG];
  1113. /*
  1114. * Set the users process environment. Store protected variables and
  1115. * obtain updated user environment list. This call will initialize
  1116. * global 'newenv'.
  1117. */
  1118. #define SESSION_PENV (PENV_INIT | PENV_ARGV | PENV_NOEXEC)
  1119. if (setpenv(user, SESSION_PENV, verify->userEnviron, NULL) != 0)
  1120. {
  1121. Debug("Can't set process environment (user=%s)\n",user);
  1122. return(0);
  1123. }
  1124. /*
  1125. * Restore pointers to tags.
  1126. */
  1127. verify->userEnviron[SYS_ENV_TAG] = sysTag;
  1128. verify->userEnviron[USR_ENV_TAG] = usrTag;
  1129. /*
  1130. * Free old userEnviron and replace with newenv from setpenv().
  1131. */
  1132. freeEnv(verify->userEnviron);
  1133. verify->userEnviron = newenv;
  1134. }
  1135. #endif /* _POWER */
  1136. #endif /* AIXV3 */
  1137. #if defined(PAM)
  1138. if (PamSetCred( verify->argv[0],
  1139. user, verify->uid, verify->gid) > 0 ) {
  1140. Debug("Can't set User's Credentials (user=%s)\n",user);
  1141. return(0);
  1142. }
  1143. #endif
  1144. #ifdef SUNAUTH
  1145. if ( solaris_setcred(verify->argv[0],
  1146. user, verify->uid, verify->gid) > 0 ) {
  1147. Debug("Can't set User's Credentials (user=%s)\n",user);
  1148. return(0);
  1149. }
  1150. #endif /* SUNAUTH */
  1151. #ifndef sun
  1152. #ifdef BLS
  1153. /*
  1154. * HP BLS B1 session setup...
  1155. *
  1156. * 1. look up user's protected account information.
  1157. * 2. set the session sensitivity/clearance levels
  1158. * 3. set the logical UID (LUID)
  1159. */
  1160. if ( ISSECURE ) {
  1161. Debug("BLS - Setting user's clearance, security level and luid.\n");
  1162. set_auth_parameters(1, verify->argv);
  1163. init_security();
  1164. verify->user_name = user;
  1165. strncpy(verify->terminal,d->name,15);
  1166. verify->terminal[15]='\0';
  1167. verify->pwd = getpwnam(user);
  1168. if ( verify->pwd == NULL || strlen(user) == 0 ) {
  1169. LogError(ReadCatalog(
  1170. MC_LOG_SET,MC_LOG_NO_BLSACCT,MC_DEF_LOG_NO_BLSACCT));
  1171. exit (1);
  1172. }
  1173. verify->prpwd= b1_pwd = getprpwnam(user);
  1174. verify->uid = b1_pwd->ufld.fd_uid;
  1175. if ( b1_pwd == NULL || strlen(user) == 0 ) {
  1176. LogError(ReadCatalog(
  1177. MC_LOG_SET,MC_LOG_NO_BLSPACCT,MC_DEF_LOG_NO_BLSPACCT));
  1178. exit (1);
  1179. }
  1180. /*
  1181. * This has already been done successfully by dtgreet
  1182. * but we need to get all the information again for the
  1183. * dtlogin process.
  1184. */
  1185. if ( verify_user_seclevel(verify,sensitivityLevel) != 1 ) {
  1186. Debug("BLS - Could not verify sensitivity level.\n");
  1187. LogError(ReadCatalog(
  1188. MC_LOG_SET,MC_LOG_NO_VFYLVL,MC_DEF_LOG_NO_VFYLVL));
  1189. exit (1);
  1190. }
  1191. if ( change_to_user(verify) != 1 ) {
  1192. Debug("BLS - Could not change to user: %s.\n",verify->user_name);
  1193. LogError(ReadCatalog(
  1194. MC_LOG_SET,MC_LOG_NO_BLSUSR,MC_DEF_LOG_NO_BLSUSR),
  1195. verify->user_name);
  1196. exit (1);
  1197. }
  1198. Debug("BLS - Session setup complete.\n");
  1199. } else {
  1200. #endif /* BLS */
  1201. # ifdef __AFS
  1202. if ( IsVerifyName(VN_AFS) ) {
  1203. pagval = get_pag_from_groups(verify->groups[0], verify->groups[1]);
  1204. Debug("AFS - get_pag_from_groups() returned pagval = %d\n", pagval);
  1205. initgroups(greet.name, verify->groups[2]);
  1206. ngroups = getgroups(NGROUPS, groups);
  1207. Debug("AFS - getgroups() returned ngroups = %d\n", ngroups);
  1208. for (i=0; i < ngroups; i++)
  1209. Debug("AFS - groups[%d] = %d\n", i, groups[i]);
  1210. if ((pagval != NOPAG) &&
  1211. (get_pag_from_groups(groups[0], groups[1])) == NOPAG ) {
  1212. /* we will have to shift grouplist to make room for pag */
  1213. if (ngroups+2 > NGROUPS)
  1214. ngroups=NGROUPS-2;
  1215. for (j=ngroups-1; j >= 0; j--) {
  1216. groups[j+2] = groups[j];
  1217. }
  1218. ngroups += 2;
  1219. get_groups_from_pag(pagval, &groups[0], &groups[1]);
  1220. if (setgroups(ngroups, groups) == -1) {
  1221. LogError(
  1222. ReadCatalog(
  1223. MC_LOG_SET,MC_LOG_AFS_FAIL,MC_DEF_LOG_AFS_FAIL));
  1224. exit(1);
  1225. }
  1226. }
  1227. }
  1228. # else /* ! __AFS */
  1229. /* If SIA is enabled, the initgroups and setgid calls are redundant
  1230. * so skip them.
  1231. */
  1232. # ifndef SIA
  1233. # ifdef NGROUPS
  1234. /*
  1235. * if your system does not support "initgroups(3C)", use
  1236. * the "setgroups()" call instead...
  1237. */
  1238. # if defined(__hpux)
  1239. initgroups(user, -1);
  1240. # else
  1241. setgroups (verify->ngroups, verify->groups);
  1242. # endif
  1243. /* setpenv() will set gid for AIX */
  1244. #if !defined (_AIX)
  1245. if(-1 == setgid (verify->groups[0])) {
  1246. perror(strerror(errno));
  1247. }
  1248. #endif
  1249. # else /* ! NGROUPS */
  1250. /* setpenv() will set gid for AIX */
  1251. #if !defined (_AIX)
  1252. setgid (verify->gid);
  1253. #endif
  1254. # endif /* NGROUPS */
  1255. # endif /* !SIA */
  1256. # endif /* __AFS */
  1257. # ifdef AUDIT
  1258. setaudid(verify->audid);
  1259. setaudproc(verify->audflg);
  1260. # endif
  1261. /* setpenv() will set uid for AIX */
  1262. #if !defined(_AIX)
  1263. if (setuid(verify->uid) != 0) {
  1264. Debug( "Setuid failed for user %s, errno = %d\n", user, errno);
  1265. LogError(ReadCatalog(
  1266. MC_LOG_SET,MC_LOG_FAIL_SETUID,MC_DEF_LOG_FAIL_SETUID),
  1267. user,errno);
  1268. exit (1);
  1269. }
  1270. #endif
  1271. #ifdef BLS
  1272. } /* ends the else clause of if ( ISSECURE ) */
  1273. #endif /* BLS */
  1274. #endif /* ! sun */
  1275. /*
  1276. * check home directory again...
  1277. */
  1278. #ifndef SIA
  1279. /* Don't need to do this if SIA is enabled, already been done.
  1280. */
  1281. home = getEnv (verify->userEnviron, "HOME");
  1282. if (home) {
  1283. if (chdir (home) == -1) {
  1284. LogError (ReadCatalog(
  1285. MC_LOG_SET,MC_LOG_NO_HMDIR,MC_DEF_LOG_NO_HMDIR),
  1286. home, getEnv (verify->userEnviron, "USER"));
  1287. if(-1 == chdir ("/")) {
  1288. perror(strerror(errno));
  1289. }
  1290. verify->userEnviron = setEnv(verify->userEnviron,
  1291. "HOME", "/");
  1292. }
  1293. else if(!failsafe) {
  1294. strcpy(lastsessfile,home); /* save user's last session */
  1295. strcat(lastsessfile,LAST_SESSION_FILE);
  1296. if((lastsession = fopen(lastsessfile,"w")) == NULL)
  1297. Debug("Unable to open file for writing: %s\n",lastsessfile);
  1298. else{
  1299. fputs(verify->argv[0],lastsession);
  1300. fclose(lastsession);
  1301. }
  1302. }
  1303. }
  1304. #endif
  1305. SetUserAuthorization (d, verify);
  1306. /*
  1307. * clear password...
  1308. */
  1309. if (greet.password)
  1310. bzero(greet.password, strlen(greet.password));
  1311. #ifdef BLS
  1312. /*
  1313. * Write login information to a file
  1314. * The file name should really be settable by some kind of resource
  1315. * but time is short so we hard-wire it to ".dtlogininfo".
  1316. */
  1317. if ( ! writeLoginInfo( ".dtlogininfo" , verify ) )
  1318. Debug("Unable to write \".dtlogininfo\"\n");
  1319. # ifndef NDEBUG
  1320. /* extra debugging */
  1321. if(!dump_sec_debug_info(verify)) {
  1322. Debug("Something wrong with environment\n");
  1323. exit(1);
  1324. }
  1325. # endif /* ! NDEBUG */
  1326. #endif /* BLS */
  1327. /*
  1328. * exec session...
  1329. */
  1330. if (verify->argv) {
  1331. if ( !failsafe) {
  1332. Debug ("Executing session %s\n", verify->argv[0]);
  1333. execute (verify->argv, verify->userEnviron);
  1334. LogError(ReadCatalog(
  1335. MC_LOG_SET,MC_LOG_SES_EXEFAIL,MC_DEF_LOG_SES_EXEFAIL),
  1336. verify->argv[0]);
  1337. }
  1338. } else {
  1339. LogError(ReadCatalog(
  1340. MC_LOG_SET,MC_LOG_NO_CMDARG,MC_DEF_LOG_NO_CMDARG));
  1341. }
  1342. /*
  1343. * specify a font for the multi-byte languages...
  1344. */
  1345. font = NULL;
  1346. lang = getEnv (verify->userEnviron, "LANG");
  1347. i = 0;
  1348. if ( password ) {
  1349. #if defined(_AIX)
  1350. failsafeArgv[i++] = "/usr/bin/X11/aixterm";
  1351. #elif defined(sun)
  1352. failsafeArgv[i++] = "/usr/openwin/bin/xterm";
  1353. #elif defined(__hpux)
  1354. failsafeArgv[i++] = "/usr/bin/X11/hpterm";
  1355. #elif defined(__OpenBSD__)
  1356. failsafeArgv[i++] = "/usr/X11R6/bin/xterm";
  1357. #elif defined(__NetBSD__)
  1358. failsafeArgv[i++] = "/usr/X11R7/bin/xterm";
  1359. #elif defined(__FreeBSD__)
  1360. failsafeArgv[i++] = "/usr/local/bin/xterm";
  1361. #else
  1362. failsafeArgv[i++] = "/usr/bin/X11/xterm";
  1363. #endif
  1364. failsafeArgv[i++] = "-geometry";
  1365. failsafeArgv[i++] = "80x10";
  1366. failsafeArgv[i++] = "-bg";
  1367. failsafeArgv[i++] = "white";
  1368. failsafeArgv[i++] = "-fg";
  1369. failsafeArgv[i++] = "black";
  1370. #ifdef _AIX
  1371. /* aixterm requires -lang option. */
  1372. failsafeArgv[i++] = "-lang";
  1373. failsafeArgv[i++] = lang;
  1374. #else /* _AIX */
  1375. failsafeArgv[i++] = "-fn";
  1376. if (font == NULL) font = "fixed";
  1377. failsafeArgv[i++] = font;
  1378. #endif /* _AIX */
  1379. failsafeArgv[i++] = "-e";
  1380. failsafeArgv[i++] = "/bin/passwd";
  1381. #if defined(__PASSWD_ETC)
  1382. failsafeArgv[i++] = "-n";
  1383. #endif
  1384. failsafeArgv[i++] = getEnv (verify->userEnviron, "USER");
  1385. }
  1386. else {
  1387. failsafeArgv[i++] = d->failsafeClient;
  1388. #ifdef sun
  1389. failsafeArgv[i++] = "-C";
  1390. #endif
  1391. failsafeArgv[i++] = "-ls";
  1392. if (font != NULL) {
  1393. failsafeArgv[i++] = "-fn";
  1394. failsafeArgv[i++] = font;
  1395. }
  1396. }
  1397. failsafeArgv[i] = 0;
  1398. Debug ("Executing failsafe session\n", failsafeArgv[0]);
  1399. execute (failsafeArgv, verify->userEnviron);
  1400. exit (1);
  1401. case -1:
  1402. Debug ("StartSession(): fork failed\n");
  1403. LogError(ReadCatalog(MC_LOG_SET,MC_LOG_NO_SESFORK,MC_DEF_LOG_NO_SESFORK),
  1404. d->name);
  1405. return 0;
  1406. default:
  1407. Debug ("StartSession(): fork succeeded, pid = %d\n", pid);
  1408. *pidp = pid;
  1409. return 1;
  1410. }
  1411. }
  1412. static jmp_buf tenaciousClient;
  1413. static SIGVAL
  1414. waitAbort( int arg )
  1415. {
  1416. longjmp (tenaciousClient, 1);
  1417. }
  1418. #if defined(SYSV) || defined(SVR4)
  1419. # include <ctype.h>
  1420. #define killpg(pgrp, sig) kill(-(pgrp), sig)
  1421. #endif /* SYSV */
  1422. static int
  1423. AbortClient( int pid )
  1424. {
  1425. int sig = SIGTERM;
  1426. #ifdef __STDC__
  1427. volatile int i;
  1428. #else
  1429. int i;
  1430. #endif
  1431. int retId;
  1432. for (i = 0; i < 4; i++) {
  1433. if (killpg (pid, sig) == -1) {
  1434. switch (errno) {
  1435. case EPERM:
  1436. LogError(ReadCatalog(
  1437. MC_LOG_SET,MC_LOG_NO_KILLCL,MC_DEF_LOG_NO_KILLCL));
  1438. case EINVAL:
  1439. case ESRCH:
  1440. return 0;
  1441. }
  1442. }
  1443. if (!setjmp (tenaciousClient)) {
  1444. (void) signal (SIGALRM, waitAbort);
  1445. (void) alarm ((unsigned) 10);
  1446. retId = wait ((waitType *) 0);
  1447. (void) alarm ((unsigned) 0);
  1448. (void) signal (SIGALRM, SIG_DFL);
  1449. if (retId == pid)
  1450. break;
  1451. } else
  1452. signal (SIGALRM, SIG_DFL);
  1453. sig = SIGKILL;
  1454. }
  1455. return 1;
  1456. }
  1457. int
  1458. source( struct verify_info *verify, char *file )
  1459. {
  1460. char *args[2];
  1461. int pid;
  1462. waitType result;
  1463. if (file && file[0]) {
  1464. Debug ("Source(): %s\n", file);
  1465. switch (pid = fork ()) {
  1466. case 0:
  1467. CleanUpChild ();
  1468. args[0] = file;
  1469. args[1] = NULL;
  1470. execute (args, verify->systemEnviron);
  1471. LogError(ReadCatalog(
  1472. MC_LOG_SET,MC_LOG_NO_EXE,MC_DEF_LOG_NO_EXE),args[0]);
  1473. exit (1);
  1474. case -1:
  1475. Debug ("Source(): fork failed\n");
  1476. LogError(ReadCatalog(
  1477. MC_LOG_SET,MC_LOG_NO_FORK,MC_DEF_LOG_NO_FORK),file);
  1478. return 1;
  1479. break;
  1480. default:
  1481. while (wait (&result) != pid)
  1482. ;
  1483. break;
  1484. }
  1485. return waitVal (result);
  1486. }
  1487. return 0;
  1488. }
  1489. /* returns 0 on failure, -1 on out of mem, and 1 on success */
  1490. int
  1491. execute(char **argv, char **environ )
  1492. {
  1493. /*
  1494. * make stdout follow stderr to the log file...
  1495. */
  1496. dup2 (2,1);
  1497. session_execve (argv[0], argv, environ);
  1498. /*
  1499. * In case this is a shell script which hasn't been made executable
  1500. * (or this is a SYSV box), do a reasonable thing...
  1501. */
  1502. #ifdef _AIX
  1503. /* errno is EACCES if not executable */
  1504. if (errno == ENOEXEC || errno == EACCES) {
  1505. #else /* _AIX */
  1506. if (errno == ENOEXEC) {
  1507. #endif /* _AIX */
  1508. char program[1024], *e, *p, *optarg;
  1509. FILE *f;
  1510. char **newargv, **av;
  1511. int argc;
  1512. /*
  1513. * emulate BSD kernel behaviour -- read
  1514. * the first line; check if it starts
  1515. * with "#!", in which case it uses
  1516. * the rest of the line as the name of
  1517. * program to run. Else use "/bin/sh".
  1518. */
  1519. f = fopen (argv[0], "r");
  1520. if (!f)
  1521. return 0;
  1522. if (fgets (program, sizeof (program) - 1, f) == NULL)
  1523. {
  1524. fclose (f);
  1525. return 0;
  1526. }
  1527. fclose (f);
  1528. e = program + strlen (program) - 1;
  1529. if (*e == '\n')
  1530. *e = '\0';
  1531. if (!strncmp (program, "#!", 2)) {
  1532. p = program + 2;
  1533. while (*p && isspace (*p))
  1534. ++p;
  1535. optarg = p;
  1536. while (*optarg && !isspace (*optarg))
  1537. ++optarg;
  1538. if (*optarg) {
  1539. *optarg = '\0';
  1540. do
  1541. ++optarg;
  1542. while (*optarg && isspace (*optarg));
  1543. } else
  1544. optarg = 0;
  1545. } else {
  1546. p = "/bin/sh";
  1547. optarg = 0;
  1548. }
  1549. Debug ("Shell script execution: %s (optarg %s)\n",
  1550. p, optarg ? optarg : "(null)");
  1551. for (av = argv, argc = 0; *av; av++, argc++)
  1552. ;
  1553. newargv = (char **) malloc ((argc + (optarg ? 3 : 2)) * sizeof (char *));
  1554. if (!newargv)
  1555. return -1;
  1556. av = newargv;
  1557. *av++ = p;
  1558. if (optarg)
  1559. *av++ = optarg;
  1560. while (*av++ = *argv++)
  1561. ;
  1562. session_execve (newargv[0], newargv, environ);
  1563. }
  1564. return 1;
  1565. }
  1566. /*****************************************************************************
  1567. * RunGreeter
  1568. *
  1569. * Invoke the Greeter process and wait for completion. If the user was
  1570. * successfully verified, return to the calling process. If the user
  1571. * selected a restart or abort option, or there was an error invoking the
  1572. * Greeter, exit this entire process with appropriate status.
  1573. *
  1574. *****************************************************************************/
  1575. #define MSGSIZE 512
  1576. extern int session_set;
  1577. extern char *progName; /* Global argv[0]; dtlogin name and path */
  1578. int response[2], request[2];
  1579. /* Fixes problem with dtlogin signal handling */
  1580. static int greeterPid = 0;
  1581. static struct display *greeter_d = NULL;
  1582. static SIGVAL
  1583. catchHUP(int arg)
  1584. {
  1585. Debug("Caught SIGHUP\n");
  1586. if (greeterPid)
  1587. {
  1588. Debug("Killing greeter process: %d\n", greeterPid);
  1589. kill(greeterPid, SIGHUP);
  1590. }
  1591. if (greeter_d)
  1592. SessionExit(greeter_d, REMANAGE_DISPLAY);
  1593. else
  1594. exit(REMANAGE_DISPLAY);
  1595. }
  1596. static void
  1597. RunGreeter( struct display *d, struct greet_info *greet,
  1598. struct verify_info *verify )
  1599. {
  1600. int pid;
  1601. waitType status;
  1602. int rbytes;
  1603. static char msg[MSGSIZE];
  1604. char *p;
  1605. char **env;
  1606. char *path;
  1607. struct greet_state state;
  1608. int notify_dt;
  1609. int dupfp = -1;
  1610. int dupfp2 = -1;
  1611. #ifdef __PASSWD_ETC
  1612. # ifndef U_NAMELEN
  1613. # define U_NAMELEN sizeof(rgy_$name_t)
  1614. # endif
  1615. int i;
  1616. static char name_short[U_NAMELEN];
  1617. #endif
  1618. #ifdef SIA
  1619. int argc = 1;
  1620. char *argv[] = { "dtlogin", 0 };
  1621. char *hostName = NULL;
  1622. char *loginName = NULL;
  1623. int siaStatus = -1;
  1624. /*
  1625. * Initialize SIA
  1626. */
  1627. if (d->serverPid == -1)
  1628. hostName = d->name;
  1629. siaStatus = sia_ses_init(&siaHandle, argc, argv, hostName,
  1630. loginName, d->name, 1, NULL);
  1631. if (siaStatus != SIASUCCESS)
  1632. {
  1633. Debug("sia_ses_init failure status %d\n", siaStatus);
  1634. exit(1);
  1635. }
  1636. #endif
  1637. greeterPid = 0;
  1638. if (!setjmp (abortSession)) {
  1639. signal(SIGTERM, catchTerm);
  1640. /*
  1641. * We've changed dtlogin to pass HUP's down to the children
  1642. * so ignore any HUP's once the client has started.
  1643. */
  1644. greeter_d = d;
  1645. signal(SIGHUP, catchHUP);
  1646. /*
  1647. * set up communication pipes...
  1648. */
  1649. if(-1 == pipe(response)) {
  1650. perror(strerror(errno));
  1651. }
  1652. if(-1 == pipe(request)) {
  1653. perror(strerror(errno));
  1654. }
  1655. rbytes = 0;
  1656. switch (greeterPid = fork ()) {
  1657. case 0:
  1658. /*
  1659. * pass some information in the environment...
  1660. */
  1661. env = 0;
  1662. sprintf(msg,"%d", d->grabServer);
  1663. env = setEnv(env, GRABSERVER, msg);
  1664. sprintf(msg,"%d", d->grabTimeout);
  1665. env = setEnv(env, GRABTIMEOUT, msg);
  1666. if (timeZone && strlen(timeZone) > 0 )
  1667. env = setEnv(env, "TZ", timeZone);
  1668. if (errorLogFile && errorLogFile[0])
  1669. env = setEnv(env, ERRORLOG, errorLogFile);
  1670. if (d->authFile)
  1671. env = setEnv(env, "XAUTHORITY", d->authFile);
  1672. if (d->dtlite)
  1673. env = setEnv(env, DTLITE, "True");
  1674. if (d->session)
  1675. env = setEnv(env, SESSION, d->session);
  1676. if(session_set)
  1677. env = setEnv(env, SESSION_SET, "True");
  1678. if (d->pmSearchPath)
  1679. env = setEnv(env, "XMICONSEARCHPATH", d->pmSearchPath);
  1680. if (d->bmSearchPath)
  1681. env = setEnv(env, "XMICONBMSEARCHPATH", d->bmSearchPath);
  1682. #if defined (__KERBEROS) || defined (__AFS)
  1683. if (d->verifyName) {
  1684. if ( (strcmp(d->verifyName, VN_AFS) == 0) ||
  1685. (strcmp(d->verifyName, VN_KRB) == 0) ) {
  1686. env = setEnv(env, VERIFYNAME, d->verifyName );
  1687. }
  1688. else {
  1689. LogError(ReadCatalog(
  1690. MC_LOG_SET,MC_LOG_IMPROP_AUTH,MC_DEF_LOG_IMPROP_AUTH),
  1691. d->verifyName);
  1692. d->verifyName = NULL;
  1693. }
  1694. }
  1695. #endif
  1696. if((path = getenv("NLSPATH")) != NULL)
  1697. env = setEnv(env, "NLSPATH", path);
  1698. /*
  1699. * ping remote displays...
  1700. *
  1701. */
  1702. if (d->displayType.location == Local) {
  1703. GettyRunning(d); /* refresh gettyState */
  1704. if (d->gettyState != DM_GETTY_USER)
  1705. env = setEnv(env, LOCATION, "local");
  1706. }
  1707. else {
  1708. sprintf(msg,"%d", d->pingInterval);
  1709. env = setEnv(env, PINGINTERVAL, msg);
  1710. sprintf(msg,"%d", d->pingTimeout);
  1711. env = setEnv(env, PINGTIMEOUT, msg);
  1712. }
  1713. if ( d->langList && strlen(d->langList) > 0 )
  1714. env = setEnv(env, LANGLIST, d->langList);
  1715. #if !defined (ENABLE_DYNAMIC_LANGLIST)
  1716. else if (strlen(languageList) > 0 )
  1717. env = setEnv(env, LANGLIST, languageList);
  1718. #endif /* ENABLE_DYNAMIC_LANGLIST */
  1719. {
  1720. char *language = NULL;
  1721. #if defined (ENABLE_DYNAMIC_LANGLIST)
  1722. language = d->language;
  1723. #endif /* ENABLE_DYNAMIC_LANGLIST */
  1724. if (env && d->language && strlen(d->language) > 0 )
  1725. env = setLang(d, env, language);
  1726. }
  1727. if((path = getenv("XKEYSYMDB")) != NULL)
  1728. env = setEnv(env, "XKEYSYMDB", path);
  1729. #ifdef sun
  1730. if((path = getenv("OPENWINHOME")) != NULL)
  1731. env = setEnv(env, "OPENWINHOME", path);
  1732. #endif
  1733. Debug ("Greeter environment:\n");
  1734. printEnv(env);
  1735. Debug ("End of Greeter environment:\n");
  1736. /*
  1737. * Writing to file descriptor 1 goes to response pipe instead.
  1738. */
  1739. close(1);
  1740. dupfp = dup(response[1]);
  1741. if(-1 == dupfp) {
  1742. perror(strerror(errno));
  1743. }
  1744. close(response[0]);
  1745. close(response[1]);
  1746. /*
  1747. * Reading from file descriptor 0 reads from request pipe instead.
  1748. */
  1749. close(0);
  1750. dupfp2 = dup(request[0]);
  1751. if(-1 == dupfp2) {
  1752. perror(strerror(errno));
  1753. }
  1754. close(request[0]);
  1755. close(request[1]);
  1756. CleanUpChild ();
  1757. /*
  1758. * figure out path to dtgreet...
  1759. */
  1760. snprintf(msg, sizeof(msg), "%s", progName);
  1761. if ((p = (char *) strrchr(msg, '/')) == NULL)
  1762. strcpy(msg,"./");
  1763. else
  1764. *(++p) = '\0';
  1765. strcat(msg,"dtgreet");
  1766. execle(msg, "dtgreet", "-display", d->name, (char *)0, env);
  1767. LogError(ReadCatalog(
  1768. MC_LOG_SET,MC_LOG_NO_DTGREET,MC_DEF_LOG_NO_DTGREET),
  1769. msg, d->name);
  1770. exit (NOTIFY_ABORT_DISPLAY);
  1771. case -1:
  1772. Debug ("Fork of Greeter failed.\n");
  1773. LogError(ReadCatalog(
  1774. MC_LOG_SET,MC_LOG_NO_FORKCG,MC_DEF_LOG_NO_FORKCG),d->name);
  1775. close(request[0]);
  1776. close(request[1]);
  1777. close(response[0]);
  1778. close(response[1]);
  1779. exit (UNMANAGE_DISPLAY);
  1780. default:
  1781. Debug ("Greeter started\n");
  1782. close(response[1]); /* Close write end of response pipe */
  1783. close(request[0]); /* Close read end of request pipe */
  1784. /*
  1785. * Retrieve information from greeter and authenticate.
  1786. */
  1787. globalDisplayName = d->name;
  1788. state.id = GREET_STATE_ENTER;
  1789. state.waitForResponse = FALSE;
  1790. #ifdef SIA
  1791. /*
  1792. * atexit() registers this function to be called if exit() is
  1793. * called. This is needed because in enhanced security mode, SIA
  1794. * may call exit() whn the user fails to enter or change a
  1795. * password.
  1796. */
  1797. sia_greeter_pid = greeterPid;
  1798. if (!sia_exit_proc_reg)
  1799. {
  1800. atexit(KillGreeter);
  1801. sia_exit_proc_reg = TRUE;
  1802. }
  1803. siaGreeterInfo.d = d;
  1804. siaGreeterInfo.greet = greet;
  1805. siaGreeterInfo.verify = verify;
  1806. siaGreeterInfo.state = &state;
  1807. siaGreeterInfo.status = TRUE;
  1808. siaStatus = -1;
  1809. while(siaStatus != SIASUCCESS)
  1810. {
  1811. while(siaStatus != SIASUCCESS && siaGreeterInfo.status)
  1812. {
  1813. Debug ("RunGreeter: before sia_ses_authent\n");
  1814. dt_in_sia_ses_authent = True;
  1815. siaStatus = sia_ses_authent(SiaManageGreeter, NULL,
  1816. siaHandle);
  1817. dt_in_sia_ses_authent = False;
  1818. Debug ("RunGreeter: after sia_ses_authent status = %d\n",
  1819. siaStatus);
  1820. if (siaStatus == SIAFAIL && siaGreeterInfo.status)
  1821. {
  1822. state.id = GREET_STATE_ERRORMESSAGE;
  1823. state.vf = VF_INVALID;
  1824. ManageGreeter(d, greet, verify, &state);
  1825. }
  1826. if (!siaGreeterInfo.status || siaStatus == SIASTOP)
  1827. break;
  1828. }
  1829. if (!siaGreeterInfo.status || siaStatus == SIASTOP)
  1830. {
  1831. sia_ses_release(&siaHandle);
  1832. break;
  1833. }
  1834. Debug("RunGreeter: before sia_ses_estab\n");
  1835. siaStatus = sia_ses_estab(SiaManageGreeter, siaHandle);
  1836. Debug ("RunGreeter: after sia_ses_estab status = %d\n",
  1837. siaStatus);
  1838. if (!siaGreeterInfo.status)
  1839. break;
  1840. if (siaStatus == SIASUCCESS)
  1841. {
  1842. Debug("RunGreeter: before sia_ses_launch\n");
  1843. siaStatus = sia_ses_launch(SiaManageGreeter, siaHandle);
  1844. Debug("RunGreeter: after sia_ses_launch status = %d\n",
  1845. siaStatus);
  1846. }
  1847. if (!siaGreeterInfo.status)
  1848. break;
  1849. if (siaStatus != SIASUCCESS)
  1850. {
  1851. Debug("RunGreeter: sia_ses_launch failure\n");
  1852. /* establish & launch failures do a release */
  1853. siaHandle = NULL;
  1854. siaStatus = sia_ses_init(&siaHandle, argc, argv, hostName,
  1855. loginName, d->name, 1, NULL);
  1856. if (siaStatus != SIASUCCESS)
  1857. {
  1858. Debug("sia_ses_init failure status %d\n", siaStatus);
  1859. exit(RESERVER_DISPLAY);
  1860. }
  1861. }
  1862. }
  1863. /*
  1864. * sia_ses_launch() wil probably seteuid to that of the
  1865. * user, but we don't want that now.
  1866. */
  1867. seteuid(0);
  1868. /*
  1869. * extract necessary info from SIA context struct
  1870. */
  1871. if (siaHandle)
  1872. {
  1873. if (siaStatus == SIASUCCESS)
  1874. CopySiaInfo(siaHandle, greet);
  1875. sia_ses_release(&siaHandle);
  1876. }
  1877. state.id = GREET_STATE_TERMINATEGREET;
  1878. if (siaGreeterInfo.status)
  1879. {
  1880. while (ManageGreeter(d, greet, verify, &state))
  1881. ;
  1882. }
  1883. sia_greeter_pid = 0;
  1884. #else
  1885. while (ManageGreeter(d, greet, verify, &state))
  1886. ;
  1887. #endif /* SIA */
  1888. /*
  1889. * Wait for Greeter to end...
  1890. */
  1891. for (;;) {
  1892. pid = wait (&status);
  1893. if (pid == greeterPid)
  1894. break;
  1895. }
  1896. /*
  1897. * Greeter exited. Check return code...
  1898. */
  1899. Debug("Greeter return status; exit = %d, signal = %d\n",
  1900. waitCode(status), waitSig(status));
  1901. /*
  1902. * remove authorization file if used...
  1903. */
  1904. if (d->authorizations && d->authFile &&
  1905. waitVal(status) != NOTIFY_LANG_CHANGE
  1906. #ifdef BLS
  1907. && waitVal(status) != NOTIFY_BAD_SECLEVEL
  1908. #endif
  1909. ) {
  1910. /***
  1911. Debug ("Done with authorization file %s, removing\n",
  1912. d->authFile);
  1913. (void) unlink (d->authFile);
  1914. ***/
  1915. }
  1916. if(waitVal(status) > NOTIFY_ALT_DTS)
  1917. d->sessionType = waitVal(status);
  1918. switch (waitVal(status)) {
  1919. case NOTIFY_FAILSAFE:
  1920. greet->string = "failsafe";
  1921. break;
  1922. case NOTIFY_PASSWD_EXPIRED:
  1923. greet->string = "password";
  1924. break;
  1925. case NOTIFY_DTLITE:
  1926. case NOTIFY_DT:
  1927. case NOTIFY_OK:
  1928. case NOTIFY_LAST_DT:
  1929. d->sessionType = waitVal(status);
  1930. break;
  1931. default:
  1932. break;
  1933. }
  1934. Debug("waitVal - status is %d\n", waitVal(status));
  1935. if(waitVal(status) > NOTIFY_ALT_DTS)
  1936. notify_dt = NOTIFY_ALT_DTS; /* It is alt desktops */
  1937. else
  1938. notify_dt = waitVal(status);
  1939. switch (notify_dt) {
  1940. case NOTIFY_FAILSAFE:
  1941. case NOTIFY_PASSWD_EXPIRED:
  1942. case NOTIFY_DTLITE:
  1943. case NOTIFY_DT:
  1944. case NOTIFY_OK:
  1945. case NOTIFY_LAST_DT:
  1946. case NOTIFY_ALT_DTS:
  1947. if (NULL == greet->name) return;
  1948. /*
  1949. * greet->name, greet->password set in ManageGreeter().
  1950. */
  1951. Debug("Greeter returned name '%s'\n", greet->name);
  1952. #ifdef __PASSWD_ETC
  1953. greet->name_full = greet->name;
  1954. /* get just person name out of full SID */
  1955. i = 0;
  1956. while (i < sizeof(rgy_$name_t)
  1957. && greet->name_full[i] != '.'
  1958. && greet->name_full[i] != '\0') {
  1959. name_short[i] = greet->name_full[i];
  1960. i++;
  1961. }
  1962. name_short[i] = '\0';
  1963. greet->name = name_short;
  1964. #endif
  1965. #ifdef __AFS
  1966. /*
  1967. * groups[] set in Authenticate().
  1968. */
  1969. if ( IsVerifyName(VN_AFS) ) {
  1970. verify->groups[0] = groups[0];
  1971. verify->groups[1] = groups[1];
  1972. Debug("Greeter returned groups[0] '%d'\n", verify->groups[0]);
  1973. Debug("Greeter returned groups[1] '%d'\n", verify->groups[1]);
  1974. }
  1975. #endif
  1976. #ifdef BLS
  1977. /*
  1978. * sensitivityLevel set in BLS_Verify()
  1979. */
  1980. greet->b1security = sensitivityLevel;
  1981. #endif
  1982. Verify(d, greet, verify);
  1983. return;
  1984. case NOTIFY_ABORT:
  1985. Debug ("Greeter Xlib error or SIGTERM\n");
  1986. SessionExit(d, OPENFAILED_DISPLAY);
  1987. case NOTIFY_RESTART:
  1988. Debug ("Greeter requested RESTART_DISPLAY\n");
  1989. SessionExit(d, RESERVER_DISPLAY);
  1990. case NOTIFY_ABORT_DISPLAY:
  1991. Debug ("Greeter requested UNMANAGE_DISPLAY\n");
  1992. SessionExit(d, UNMANAGE_DISPLAY);
  1993. case NOTIFY_NO_WINDOWS:
  1994. Debug ("Greeter requested NO_WINDOWS mode\n");
  1995. if (d->serverPid >= 2)
  1996. /*
  1997. * Don't do a SessionExit() here since that causes
  1998. * the X-server to be reset. We know we are going to
  1999. * terminate it anyway, so just go do that...
  2000. */
  2001. exit(SUSPEND_DISPLAY);
  2002. else
  2003. return;
  2004. case NOTIFY_LANG_CHANGE:
  2005. Debug ("Greeter requested LANG_CHANGE\n");
  2006. /*
  2007. * copy requested language into display struct "d". Note,
  2008. * this only happens in this child's copy of "d", not in
  2009. * the master struct. When the user logs out, the
  2010. * resource-specified language (if any) will reactivate.
  2011. */
  2012. if (d->language)
  2013. Debug("Greeter returned language '%s'\n", d->language);
  2014. else
  2015. Debug("Greeter returned language (NULL)\n");
  2016. if (strcmp(d->language, "default") == 0) {
  2017. int len = strlen(defaultLanguage) + 1;
  2018. d->language = (d->language == NULL ?
  2019. malloc(len) : realloc (d->language, len));
  2020. strcpy(d->language, defaultLanguage);
  2021. }
  2022. return;
  2023. #ifdef BLS
  2024. case NOTIFY_BAD_SECLEVEL:
  2025. return;
  2026. #endif
  2027. case waitCompose (SIGTERM,0,0):
  2028. Debug ("Greeter exited on SIGTERM\n");
  2029. SessionExit(d, OPENFAILED_DISPLAY);
  2030. default:
  2031. Debug ("Greeter returned unknown status %d\n",
  2032. waitVal(status));
  2033. SessionExit(d, REMANAGE_DISPLAY);
  2034. }
  2035. }
  2036. signal(SIGHUP, SIG_DFL);
  2037. }
  2038. else {
  2039. AbortClient(greeterPid);
  2040. SessionExit(d, UNMANAGE_DISPLAY);
  2041. }
  2042. }
  2043. /*****************************************************************************
  2044. * ManageGreeter
  2045. State transitions
  2046. enter -> ENTER:
  2047. This is the entry into greeter state processing. Allocate and initialize
  2048. state structure.
  2049. ENTER -> LOGIN:
  2050. Display the login screen. Upon display, the login screen can be 'reset'. If
  2051. reset is true, the username and password fields are cleared and the focus
  2052. is set to the username field. If reset is false, the username and password
  2053. field is untouched and the focus is set to the password field.
  2054. LOGIN -> AUTHENTICATE:
  2055. Authenticate the username entered on login screen.
  2056. AUTHENTICATE -> TERMINATEGREET:
  2057. User passed authentication so terminate the greeter.
  2058. AUTHENTICATE -> EXPASSWORD:
  2059. User passed authentication, but the their password has expired.
  2060. Display old password message. This message allows the user to
  2061. change their password by starting a getty and running passwd(1).
  2062. AUTHENTICATE -> BAD_HOSTNAME:
  2063. User passed authentication, but the their hostname is empty.
  2064. Display a dialog that allows the user to run a getty to fix the
  2065. problem, or start the desktop anyway.
  2066. AUTHENTICATE -> ERRORMESSAGE:
  2067. User failed authentication, so display error message.
  2068. AUTHENTICATE -> LOGIN
  2069. User failed authentication, but did not enter a password. Instead
  2070. of displaying an error message, redisplay the login screen with
  2071. the focus set to the password field. If the user authenticates again
  2072. without the password field set, display an error. This allows a user
  2073. to type the ubiquitous "username<ENTER>password<ENTER>" sequence.
  2074. EXIT -> exit
  2075. Free state structure and return false to stop state transitions.
  2076. ERRORMESSAGE -> LOGIN
  2077. Display error message base on return code from last authentication
  2078. attempt. Redisplay login screen with reset set to true.
  2079. (state) -> LANG -> (state)
  2080. User has chosen a new language. Transition to LANG state to save off
  2081. the new language, and transition back to original state.
  2082. *****************************************************************************/
  2083. #define SETMC(M, ID) M.id = MC_##ID; M.def = MC_DEF_##ID
  2084. static int
  2085. ManageGreeter( struct display *d, struct greet_info *greet,
  2086. struct verify_info *verify, struct greet_state *state )
  2087. {
  2088. struct {
  2089. int id;
  2090. char *def;
  2091. } msg;
  2092. if (state->waitForResponse)
  2093. {
  2094. if (!AskGreeter(NULL, (char *)state->response, REQUEST_LIM_MAXLEN))
  2095. {
  2096. /*
  2097. * Dtgreet has terminated.
  2098. */
  2099. state->id = GREET_STATE_EXIT;
  2100. state->waitForResponse = FALSE;
  2101. return(TRUE);
  2102. }
  2103. if (state->request->opcode != state->response->opcode)
  2104. {
  2105. /*
  2106. * An unrequested event arrived. See if it's one we
  2107. * are expecting.
  2108. */
  2109. switch(state->response->opcode)
  2110. {
  2111. case REQUEST_OP_LANG:
  2112. {
  2113. /*
  2114. * User has changed language. Recursively handle this state
  2115. * and return to current state.
  2116. */
  2117. struct greet_state lang_state;
  2118. lang_state = *state;
  2119. lang_state.id = GREET_STATE_LANG;
  2120. lang_state.waitForResponse = FALSE;
  2121. ManageGreeter(d, greet, verify, &lang_state);
  2122. Debug("Response opcode REQUEST_OP_LANG\n");
  2123. return(TRUE);
  2124. }
  2125. break;
  2126. case REQUEST_OP_CLEAR:
  2127. {
  2128. /*
  2129. * User has requested the screen be cleared.
  2130. */
  2131. state->id = GREET_STATE_USERNAME;
  2132. state->waitForResponse = TRUE;
  2133. Debug("Response opcode REQUEST_OP_CLEAR\n");
  2134. }
  2135. break;
  2136. default:
  2137. Debug("Response opcode UNEXPECTED RESPONSE!\n");
  2138. #ifndef SIA
  2139. return(TRUE);
  2140. #endif
  2141. break;
  2142. }
  2143. }
  2144. else
  2145. {
  2146. /*
  2147. * Got the response we were expecting.
  2148. */
  2149. state->waitForResponse = FALSE;
  2150. }
  2151. }
  2152. switch(state->id)
  2153. {
  2154. case GREET_STATE_ENTER:
  2155. {
  2156. /*
  2157. * Enter - initialize state
  2158. */
  2159. Debug("GREET_STATE_ENTER\n");
  2160. state->request = (RequestHeader *)malloc(REQUEST_LIM_MAXLEN);
  2161. state->response= (ResponseHeader *)malloc(REQUEST_LIM_MAXLEN);
  2162. state->authenticated = FALSE;
  2163. state->msg = NULL;
  2164. state->id = GREET_STATE_USERNAME;
  2165. }
  2166. break;
  2167. case GREET_STATE_USERNAME:
  2168. {
  2169. /*
  2170. * Get user name
  2171. */
  2172. RequestChallenge *r;
  2173. Debug("GREET_STATE_USERNAME\n");
  2174. Authenticate(d, NULL, NULL, NULL);
  2175. SETMC(msg, LOGIN_LABEL);
  2176. r = (RequestChallenge *)state->request;
  2177. r->hdr.opcode = REQUEST_OP_CHALLENGE;
  2178. r->hdr.reserved = 0;
  2179. r->bEcho = TRUE;
  2180. r->idMC = msg.id;
  2181. r->hdr.length = sizeof(*r);
  2182. r->offChallenge = sizeof(*r);
  2183. strcpy(((char *)r) + r->offChallenge, msg.def);
  2184. r->hdr.length += strlen(msg.def) + 1;
  2185. if (greet->name)
  2186. {
  2187. r->offUserNameSeed = r->hdr.length;
  2188. strcpy(((char *)r) + r->offUserNameSeed, greet->name);
  2189. r->hdr.length += strlen(greet->name) + 1;
  2190. Debug("Greet name: %s\n", greet->name);
  2191. }
  2192. else
  2193. {
  2194. r->offUserNameSeed = 0;
  2195. }
  2196. if (greet->name)
  2197. {
  2198. free(greet->name); greet->name = NULL;
  2199. }
  2200. if (greet->password)
  2201. {
  2202. free(greet->password); greet->password = NULL;
  2203. }
  2204. TellGreeter((RequestHeader *)r);
  2205. state->waitForResponse = TRUE;
  2206. state->id = GREET_STATE_AUTHENTICATE;
  2207. }
  2208. break;
  2209. case GREET_STATE_CHALLENGE:
  2210. {
  2211. /*
  2212. * Get user name
  2213. */
  2214. RequestChallenge *r;
  2215. Debug("GREET_STATE_CHALLENGE\n");
  2216. if (greet->password)
  2217. {
  2218. free(greet->password); greet->password = NULL;
  2219. }
  2220. SETMC(msg, PASSWD_LABEL);
  2221. r = (RequestChallenge *)state->request;
  2222. r->hdr.opcode = REQUEST_OP_CHALLENGE;
  2223. r->hdr.reserved = 0;
  2224. r->bEcho = FALSE;
  2225. r->idMC = msg.id;
  2226. r->offUserNameSeed = 0;
  2227. r->offChallenge = sizeof(*r);
  2228. strcpy(((char *)r) + r->offChallenge, msg.def);
  2229. r->hdr.length = sizeof(*r) + strlen(msg.def) + 1;
  2230. TellGreeter((RequestHeader *)r);
  2231. state->waitForResponse = TRUE;
  2232. state->id = GREET_STATE_AUTHENTICATE;
  2233. }
  2234. break;
  2235. case GREET_STATE_AUTHENTICATE:
  2236. {
  2237. /*
  2238. * Attempt to authenticate.
  2239. */
  2240. ResponseChallenge *r;
  2241. Debug("GREET_STATE_AUTHENTICATE\n");
  2242. r = (ResponseChallenge *)state->response;
  2243. if (greet->name == NULL)
  2244. {
  2245. greet->name = strdup(((char *)r) + r->offResponse);
  2246. if (strlen(greet->name) == 0)
  2247. {
  2248. state->id = GREET_STATE_USERNAME;
  2249. break;
  2250. }
  2251. }
  2252. else
  2253. {
  2254. greet->password = strdup(((char *)r) + r->offResponse);
  2255. }
  2256. if (state->msg)
  2257. {
  2258. free(state->msg);
  2259. state->msg = NULL;
  2260. }
  2261. /*
  2262. * Attempt to authenticate user. 'username' should be a
  2263. * non-empty string. 'password' may be an empty string.
  2264. */
  2265. state->vf = Authenticate(d, greet->name, greet->password, &state->msg);
  2266. if (state->vf == VF_OK ||
  2267. state->vf == VF_PASSWD_AGED ||
  2268. state->vf == VF_BAD_HOSTNAME)
  2269. {
  2270. state->authenticated = TRUE;
  2271. }
  2272. /*
  2273. * General transitions.
  2274. */
  2275. switch (state->vf)
  2276. {
  2277. case VF_OK: state->id = GREET_STATE_TERMINATEGREET; break;
  2278. case VF_PASSWD_AGED: state->id = GREET_STATE_EXPASSWORD; break;
  2279. case VF_BAD_HOSTNAME: state->id = GREET_STATE_BAD_HOSTNAME; break;
  2280. case VF_CHALLENGE: state->id = GREET_STATE_CHALLENGE; break;
  2281. default: state->id = GREET_STATE_ERRORMESSAGE; break;
  2282. }
  2283. }
  2284. break;
  2285. case GREET_STATE_EXIT:
  2286. {
  2287. /*
  2288. * Free resources and leave.
  2289. */
  2290. Debug("GREET_STATE_EXIT\n");
  2291. if (state->msg)
  2292. {
  2293. free(state->msg);
  2294. }
  2295. if (!state->authenticated)
  2296. {
  2297. if (greet->name)
  2298. {
  2299. free(greet->name); greet->name = NULL;
  2300. }
  2301. if (greet->password)
  2302. {
  2303. free(greet->password); greet->password = NULL;
  2304. }
  2305. }
  2306. free(state->request);
  2307. free(state->response);
  2308. return(FALSE);
  2309. }
  2310. break;
  2311. case GREET_STATE_ERRORMESSAGE:
  2312. {
  2313. /*
  2314. * Display error message.
  2315. */
  2316. RequestMessage *r;
  2317. Debug("GREET_STATE_ERRORMESSAGE\n");
  2318. r = (RequestMessage *)state->request;
  2319. switch(state->vf)
  2320. {
  2321. case VF_INVALID: SETMC(msg, LOGIN); break;
  2322. case VF_HOME: SETMC(msg, HOME); break;
  2323. case VF_MAX_USERS: SETMC(msg, MAX_USERS); break;
  2324. case VF_BAD_UID: SETMC(msg, BAD_UID); break;
  2325. case VF_BAD_GID: SETMC(msg, BAD_GID); break;
  2326. case VF_BAD_AID: SETMC(msg, BAD_AID); break;
  2327. case VF_BAD_AFLAG: SETMC(msg, BAD_AFLAG); break;
  2328. case VF_NO_LOGIN: SETMC(msg, NO_LOGIN); break;
  2329. #ifdef BLS
  2330. case VF_BAD_SEN_LEVEL: SETMC(msg, BAD_SEN_LEVEL); break;
  2331. #endif
  2332. case VF_MESSAGE: msg.id=0; msg.def=state->msg; break;
  2333. default: msg.id=0; msg.def=""; break;
  2334. }
  2335. r->hdr.opcode = REQUEST_OP_MESSAGE;
  2336. r->hdr.reserved = 0;
  2337. r->idMC = msg.id;
  2338. r->offMessage = sizeof(*r);
  2339. strcpy(((char *)r) + r->offMessage, msg.def);
  2340. r->hdr.length = sizeof(*r) + strlen(msg.def) + 1;
  2341. TellGreeter((RequestHeader *)r);
  2342. state->waitForResponse = TRUE;
  2343. state->id = GREET_STATE_USERNAME;
  2344. }
  2345. break;
  2346. case GREET_STATE_LANG:
  2347. {
  2348. /*
  2349. * User selected new language.
  2350. */
  2351. ResponseLang *r;
  2352. char *lang;
  2353. int len;
  2354. Debug("GREET_STATE_LANG\n");
  2355. r = (ResponseLang *)state->response;
  2356. lang = ((char *)r) + r->offLang;
  2357. len = strlen(lang) + 1;
  2358. d->language = (d->language == NULL ?
  2359. malloc(len) : realloc(d->language, len));
  2360. strcpy(d->language, lang);
  2361. Debug("Language returned: %s\n", d->language);
  2362. }
  2363. break;
  2364. case GREET_STATE_TERMINATEGREET:
  2365. {
  2366. /*
  2367. * Terminate dtgreet.
  2368. */
  2369. RequestExit *r;
  2370. Debug("GREET_STATE_TERMINATEGREET\n");
  2371. r = (RequestExit *)state->request;
  2372. r->hdr.opcode = REQUEST_OP_EXIT;
  2373. r->hdr.reserved = 0;
  2374. r->hdr.length = sizeof(*r);
  2375. TellGreeter((RequestHeader *)r);
  2376. state->waitForResponse = TRUE;
  2377. state->id = GREET_STATE_EXIT;
  2378. }
  2379. break;
  2380. case GREET_STATE_EXPASSWORD:
  2381. {
  2382. /*
  2383. * Display password expired message.
  2384. */
  2385. RequestExpassword *r;
  2386. Debug("GREET_STATE_EXPASSWORD\n");
  2387. r = (RequestExpassword *)state->request;
  2388. r->hdr.opcode = REQUEST_OP_EXPASSWORD;
  2389. r->hdr.reserved = 0;
  2390. r->hdr.length = sizeof(*r);
  2391. TellGreeter((RequestHeader *)r);
  2392. state->waitForResponse = TRUE;
  2393. state->id = GREET_STATE_USERNAME;
  2394. }
  2395. break;
  2396. case GREET_STATE_BAD_HOSTNAME:
  2397. {
  2398. /*
  2399. * Display password expired message.
  2400. */
  2401. RequestHostname *r;
  2402. Debug("GREET_STATE_BAD_HOSTNAME\n");
  2403. r = (RequestHostname *)state->request;
  2404. r->hdr.opcode = REQUEST_OP_HOSTNAME;
  2405. r->hdr.reserved = 0;
  2406. r->hdr.length = sizeof(*r);
  2407. TellGreeter((RequestHeader *)r);
  2408. state->waitForResponse = TRUE;
  2409. state->id = GREET_STATE_USERNAME;
  2410. }
  2411. break;
  2412. #ifdef SIA
  2413. case GREET_STATE_FORM:
  2414. {
  2415. /*
  2416. * Get arbitrary number of answers.
  2417. */
  2418. Debug("GREET_STATE_FORM\n");
  2419. AskGreeter(state->request, (char *)state->response, REQUEST_LIM_MAXLEN);
  2420. state->waitForResponse = FALSE;
  2421. state->id = GREET_STATE_USERNAME;
  2422. }
  2423. break;
  2424. #endif /* SIA */
  2425. }
  2426. return(TRUE);
  2427. }
  2428. static void
  2429. TellGreeter(
  2430. RequestHeader *phdr)
  2431. {
  2432. if(-1 == write(request[1], phdr, phdr->length)) {
  2433. perror(strerror(errno));
  2434. }
  2435. }
  2436. static int
  2437. AskGreeter(
  2438. RequestHeader *preqhdr,
  2439. char *buf,
  2440. int blen)
  2441. {
  2442. int count;
  2443. int remainder;
  2444. ResponseHeader *phdr = (ResponseHeader *)buf;
  2445. if (preqhdr) TellGreeter(preqhdr);
  2446. phdr->opcode = REQUEST_OP_NONE;
  2447. count = read(response[0], buf, sizeof(*phdr));
  2448. if (count == sizeof(*phdr))
  2449. {
  2450. /*
  2451. * Calculate amount of data after header.
  2452. */
  2453. remainder = phdr->length - sizeof(*phdr);
  2454. if (remainder > 0)
  2455. {
  2456. /*
  2457. * Read remainder of response.
  2458. */
  2459. count += read(response[0], buf+sizeof(*phdr), remainder);
  2460. }
  2461. }
  2462. #if defined (DEBUG)
  2463. if (debugLevel) PrintResponse(phdr, count);
  2464. #endif /* DEBUG */
  2465. return(count);
  2466. }
  2467. #if defined (DEBUG)
  2468. static void
  2469. PrintResponse(
  2470. ResponseHeader *phdr,
  2471. int count)
  2472. {
  2473. char *opstr = "UNKNOWN";
  2474. if (!count)
  2475. {
  2476. Debug("opcode = (EOF)\n");
  2477. return;
  2478. }
  2479. switch(phdr->opcode)
  2480. {
  2481. case REQUEST_OP_EXIT: opstr = "EXIT"; break;
  2482. case REQUEST_OP_MESSAGE: opstr = "MESSAGE"; break;
  2483. case REQUEST_OP_CHPASS: opstr = "CHPASS"; break;
  2484. case REQUEST_OP_CHALLENGE: opstr = "CHALLENGE"; break;
  2485. case REQUEST_OP_LANG: opstr = "LANG"; break;
  2486. case REQUEST_OP_DEBUG: opstr = "DEBUG"; break;
  2487. }
  2488. Debug("opcode = %d (%s)\n", phdr->opcode, opstr);
  2489. Debug(" reserved = %d\n", phdr->reserved);
  2490. Debug(" length = %d\n", phdr->length);
  2491. switch(phdr->opcode)
  2492. {
  2493. case REQUEST_OP_EXIT: break;
  2494. case REQUEST_OP_LANG:
  2495. Debug(" offLang=%d\n", ((ResponseLang *)phdr)->offLang);
  2496. Debug(" lang='%s'\n",
  2497. ((char *)phdr)+((ResponseLang *)phdr)->offLang);
  2498. break;
  2499. case REQUEST_OP_MESSAGE: break;
  2500. case REQUEST_OP_CHPASS: break;
  2501. case REQUEST_OP_CHALLENGE:
  2502. Debug(" offResponse=%d\n", ((ResponseChallenge *)phdr)->offResponse);
  2503. Debug(" response='%s'\n",
  2504. ((char *)phdr)+((ResponseChallenge *)phdr)->offResponse);
  2505. break;
  2506. case REQUEST_OP_DEBUG:
  2507. Debug(" offString=%d\n", ((ResponseDebug *)phdr)->offString);
  2508. Debug(" string='%s'\n",
  2509. ((char *)phdr)+((ResponseDebug *)phdr)->offString);
  2510. break;
  2511. }
  2512. }
  2513. #endif /* DEBUG */
  2514. #ifdef __KERBEROS
  2515. /***************************************************************************
  2516. *
  2517. * SetTicketFileName
  2518. *
  2519. * generate kerberos ticket file name. Name is returned in the static
  2520. * global variable "krb_ticket_string".
  2521. *
  2522. ***************************************************************************/
  2523. static void
  2524. SetTicketFileName(uid_t uid)
  2525. {
  2526. char *env;
  2527. char lhost[64], *p;
  2528. /*
  2529. * generate ticket file pathname (/tmp/tkt<uid>.<host>) ...
  2530. */
  2531. if (env = (char *)getenv("KRBTKFILE")) {
  2532. (void) strncpy(krb_ticket_string, env, sizeof(krb_ticket_string)-1);
  2533. krb_ticket_string[sizeof(krb_ticket_string)-1] = '\0';
  2534. } else {
  2535. if (gethostname(lhost, sizeof(lhost)) != -1) {
  2536. if (p = index(lhost, '.')) *p = '\0';
  2537. (void)sprintf(krb_ticket_string, "%s%ld.%s", TKT_ROOT, (long)uid, lhost);
  2538. } else {
  2539. /* 32 bits of signed integer will always fit in 11 characters
  2540. (including the sign), so no need to worry about overflow */
  2541. (void) sprintf(krb_ticket_string, "%s%ld", TKT_ROOT, (long)uid);
  2542. }
  2543. }
  2544. }
  2545. #endif /* __KERBEROS */
  2546. #if defined (_AIX) && !defined (_POWER)
  2547. /***************************************************************************
  2548. *
  2549. * session_execve
  2550. *
  2551. * If this is an authenticated process (LOGNAME set), set user's
  2552. * process environment by calling setpenv().
  2553. *
  2554. * If this is not an authenticated process, just call execve()
  2555. *
  2556. ***************************************************************************/
  2557. static int
  2558. session_execve(
  2559. char *path,
  2560. char *argv[],
  2561. char *envp[])
  2562. {
  2563. int rc;
  2564. char *user = getEnv (envp, "LOGNAME");
  2565. if (user == NULL)
  2566. {
  2567. rc = execve(path, argv, envp);
  2568. }
  2569. else
  2570. {
  2571. char *usrTag, *sysTag;
  2572. /*
  2573. * Save pointers to tags. The setpenv() function clears the pointers
  2574. * to the tags in userEnviron as a side-effect.
  2575. */
  2576. sysTag = envp[SYS_ENV_TAG];
  2577. usrTag = envp[USR_ENV_TAG];
  2578. /*
  2579. * Set the users process environment. This call execs arvg so it
  2580. * should not return. It it should return, restore the envp tags.
  2581. */
  2582. rc = setpenv(user, PENV_INIT | PENV_ARGV, envp, argv);
  2583. /*
  2584. * Restore pointers to tags.
  2585. */
  2586. envp[SYS_ENV_TAG] = sysTag;
  2587. envp[USR_ENV_TAG] = usrTag;
  2588. }
  2589. return(rc);
  2590. }
  2591. #endif /* _AIX && !_POWER */
  2592. #ifdef SIA
  2593. /* collect the SIA parameters from a window system. */
  2594. static int SiaManageGreeter(
  2595. int timeout,
  2596. int rendition,
  2597. unsigned char *title,
  2598. int num_prompts,
  2599. prompt_t *prompt)
  2600. {
  2601. int i;
  2602. struct {
  2603. RequestMessage greeter_message;
  2604. char msg_buffer[256];
  2605. } greeter_msg_and_buffer;
  2606. RequestForm *request_form;
  2607. switch(rendition)
  2608. {
  2609. case SIAMENUONE:
  2610. case SIAMENUANY:
  2611. case SIAONELINER:
  2612. case SIAFORM:
  2613. if (rendition == SIAFORM && dt_in_sia_ses_authent
  2614. && (num_prompts == 2))
  2615. {
  2616. /* Normal login, Password case */
  2617. Debug ("SIAFORM Normal login, Password case\n");
  2618. while (siaGreeterInfo.state->id != GREET_STATE_TERMINATEGREET
  2619. && siaGreeterInfo.state->id != GREET_STATE_EXIT
  2620. && (siaGreeterInfo.status = ManageGreeter(
  2621. siaGreeterInfo.d, siaGreeterInfo.greet,
  2622. siaGreeterInfo.verify, siaGreeterInfo.state)))
  2623. ;
  2624. if (!siaGreeterInfo.status
  2625. || siaGreeterInfo.state->id == GREET_STATE_EXIT)
  2626. return(SIACOLABORT);
  2627. strncpy((char *)prompt[0].result, siaGreeterInfo.greet->name,
  2628. prompt[0].max_result_length);
  2629. strncpy((char *)prompt[1].result,siaGreeterInfo.greet->password,
  2630. prompt[1].max_result_length);
  2631. }
  2632. else
  2633. {
  2634. char *res_ptr;
  2635. char *pmpt_ptr;
  2636. int req_form_size;
  2637. ResponseForm *response_form;
  2638. switch(rendition)
  2639. {
  2640. case SIAMENUONE:
  2641. Debug("SIAMENUONE num_prompts = %d\n", num_prompts);
  2642. break;
  2643. case SIAMENUANY:
  2644. Debug("SIAMENUANY num_prompts = %d\n", num_prompts);
  2645. break;
  2646. case SIAONELINER:
  2647. Debug("SIAONELINER num_prompts = %d\n", num_prompts);
  2648. break;
  2649. case SIAFORM:
  2650. Debug("SIAFORM num_prompts = %d\n", num_prompts);
  2651. break;
  2652. }
  2653. /* need to display form */
  2654. req_form_size = sizeof(RequestForm)
  2655. + strlen((const char *)title) + 1;
  2656. for (i=0; i<num_prompts; i++)
  2657. req_form_size += strlen((const char *)prompt[i].prompt) + 1;
  2658. request_form = (RequestForm *) alloca(req_form_size);
  2659. siaGreeterInfo.state->id = GREET_STATE_FORM;
  2660. siaGreeterInfo.state->request = (RequestHeader *)request_form;
  2661. /* siaGreeterInfo.state->vf = VF_MESSAGE; */
  2662. request_form->hdr.opcode = REQUEST_OP_FORM;
  2663. request_form->hdr.reserved = 0;
  2664. request_form->hdr.length = req_form_size;
  2665. request_form->num_prompts = num_prompts;
  2666. request_form->rendition = rendition;
  2667. request_form->offTitle = sizeof(RequestForm);
  2668. request_form->offPrompts = sizeof(RequestForm) +
  2669. strlen((const char *)title) + 1;
  2670. strcpy((char *)request_form + request_form->offTitle,
  2671. (const char *)title);
  2672. pmpt_ptr = (char *)request_form + request_form->offPrompts;
  2673. for (i=0; i<num_prompts; i++)
  2674. {
  2675. if (!prompt[i].prompt || prompt[i].prompt[0] == '\0')
  2676. *pmpt_ptr++ = '\0';
  2677. else
  2678. {
  2679. Debug(" prompt[%d]: %s\n", i, prompt[i].prompt);
  2680. strcpy(pmpt_ptr, (const char *)prompt[i].prompt);
  2681. pmpt_ptr += strlen((const char *)prompt[i].prompt);
  2682. }
  2683. request_form->visible[i] =
  2684. (prompt[i].control_flags & SIARESINVIS) ? False : True;
  2685. }
  2686. siaGreeterInfo.status = ManageGreeter(siaGreeterInfo.d,
  2687. siaGreeterInfo.greet,
  2688. siaGreeterInfo.verify,
  2689. siaGreeterInfo.state);
  2690. response_form = (ResponseForm *)siaGreeterInfo.state->response;
  2691. res_ptr = (char *)response_form + response_form->offAnswers;
  2692. for (i = 0; i < response_form->num_answers; i++)
  2693. {
  2694. if (rendition == SIAMENUONE || rendition == SIAMENUANY)
  2695. {
  2696. if (res_ptr[0])
  2697. prompt[i].result = (unsigned char *)1;
  2698. else
  2699. prompt[i].result = NULL;
  2700. }
  2701. else
  2702. {
  2703. strcpy((char *)prompt[0].result, res_ptr);
  2704. }
  2705. res_ptr += strlen(res_ptr) + 1;
  2706. }
  2707. if (!response_form->collect_status)
  2708. siaGreeterInfo.status = FALSE;
  2709. }
  2710. break;
  2711. case SIAINFO:
  2712. case SIAWARNING:
  2713. Debug("SIAINFO or SIAWARNING %s\n", prompt[0].prompt);
  2714. siaGreeterInfo.state->id = GREET_STATE_ERRORMESSAGE;
  2715. siaGreeterInfo.state->request = (RequestHeader *)
  2716. &greeter_msg_and_buffer.greeter_message;
  2717. siaGreeterInfo.state->vf = VF_MESSAGE;
  2718. siaGreeterInfo.state->msg = (char *)prompt[0].prompt;
  2719. siaGreeterInfo.status = ManageGreeter(siaGreeterInfo.d,
  2720. siaGreeterInfo.greet,
  2721. siaGreeterInfo.verify,
  2722. siaGreeterInfo.state);
  2723. break;
  2724. default:
  2725. return(SIACOLABORT);
  2726. break;
  2727. }
  2728. if (!siaGreeterInfo.status)
  2729. return(SIACOLABORT);
  2730. return(SIACOLSUCCESS);
  2731. }
  2732. static CopySiaInfo(SIAENTITY *siaHandle, struct greet_info *greet)
  2733. {
  2734. greet->name = malloc(strlen(siaHandle->name) + 1);
  2735. strcpy (greet->name, siaHandle->name);
  2736. greet->password = malloc(strlen(siaHandle->password) + 1);
  2737. strcpy (greet->password, siaHandle->password);
  2738. }
  2739. static void KillGreeter( void )
  2740. {
  2741. if (sia_greeter_pid)
  2742. AbortClient(sia_greeter_pid);
  2743. sia_greeter_pid = 0;
  2744. }
  2745. #endif /* SIA */