auth.c revision 629baa8c
1629baa8cSmrg/* 2629baa8cSmrg 3629baa8cSmrgCopyright 1988, 1998 The Open Group 4629baa8cSmrg 5629baa8cSmrgPermission to use, copy, modify, distribute, and sell this software and its 6629baa8cSmrgdocumentation for any purpose is hereby granted without fee, provided that 7629baa8cSmrgthe above copyright notice appear in all copies and that both that 8629baa8cSmrgcopyright notice and this permission notice appear in supporting 9629baa8cSmrgdocumentation. 10629baa8cSmrg 11629baa8cSmrgThe above copyright notice and this permission notice shall be included 12629baa8cSmrgin all copies or substantial portions of the Software. 13629baa8cSmrg 14629baa8cSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15629baa8cSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16629baa8cSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17629baa8cSmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 18629baa8cSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19629baa8cSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20629baa8cSmrgOTHER DEALINGS IN THE SOFTWARE. 21629baa8cSmrg 22629baa8cSmrgExcept as contained in this notice, the name of The Open Group shall 23629baa8cSmrgnot be used in advertising or otherwise to promote the sale, use or 24629baa8cSmrgother dealings in this Software without prior written authorization 25629baa8cSmrgfrom The Open Group. 26629baa8cSmrg 27629baa8cSmrg*/ 28629baa8cSmrg 29629baa8cSmrg/* 30629baa8cSmrg * xdm - display manager daemon 31629baa8cSmrg * Author: Keith Packard, MIT X Consortium 32629baa8cSmrg * 33629baa8cSmrg * auth.c 34629baa8cSmrg * 35629baa8cSmrg * maintain the authorization generation daemon 36629baa8cSmrg */ 37629baa8cSmrg 38629baa8cSmrg#include <X11/X.h> 39629baa8cSmrg#include <X11/Xlibint.h> 40629baa8cSmrg#include <sys/types.h> 41629baa8cSmrg#include <sys/stat.h> 42629baa8cSmrg 43629baa8cSmrg#include "dm.h" 44629baa8cSmrg#include "dm_auth.h" 45629baa8cSmrg#include "dm_error.h" 46629baa8cSmrg 47629baa8cSmrg#include <errno.h> 48629baa8cSmrg 49629baa8cSmrg#include <sys/ioctl.h> 50629baa8cSmrg 51629baa8cSmrg#if defined(TCPCONN) || defined(STREAMSCONN) 52629baa8cSmrg# include "dm_socket.h" 53629baa8cSmrg#endif 54629baa8cSmrg#ifdef DNETCONN 55629baa8cSmrg# include <netdnet/dn.h> 56629baa8cSmrg# include <netdnet/dnetdb.h> 57629baa8cSmrg#endif 58629baa8cSmrg 59629baa8cSmrg#if defined(hpux) 60629baa8cSmrg# include <sys/utsname.h> 61629baa8cSmrg#endif 62629baa8cSmrg 63629baa8cSmrg#if defined(SYSV) && defined(i386) 64629baa8cSmrg# include <sys/stream.h> 65629baa8cSmrg# ifdef ISC 66629baa8cSmrg# include <stropts.h> 67629baa8cSmrg# include <sys/sioctl.h> 68629baa8cSmrg# endif /* ISC */ 69629baa8cSmrg#endif /* i386 */ 70629baa8cSmrg 71629baa8cSmrg#ifdef SVR4 72629baa8cSmrg# include <netdb.h> 73629baa8cSmrg# include <sys/sockio.h> 74629baa8cSmrg# include <sys/stropts.h> 75629baa8cSmrg#endif 76629baa8cSmrg#ifdef __convex__ 77629baa8cSmrg# include <sync/queue.h> 78629baa8cSmrg# include <sync/sema.h> 79629baa8cSmrg#endif 80629baa8cSmrg#ifdef __GNU__ 81629baa8cSmrg# include <netdb.h> 82629baa8cSmrg# undef SIOCGIFCONF 83629baa8cSmrg#else /* __GNU__ */ 84629baa8cSmrg# include <net/if.h> 85629baa8cSmrg#endif /* __GNU__ */ 86629baa8cSmrg 87629baa8cSmrg#if defined(TCPCONN) && !defined(WIN32) 88629baa8cSmrg# include <netinet/in.h> 89629baa8cSmrg#endif 90629baa8cSmrg 91629baa8cSmrg/* Solaris provides an extended interface SIOCGLIFCONF for IPv6 support. 92629baa8cSmrg */ 93629baa8cSmrg#ifdef SIOCGLIFCONF 94629baa8cSmrg# define USE_SIOCGLIFCONF 95629baa8cSmrg#endif 96629baa8cSmrg 97629baa8cSmrg#if ((defined(SVR4) && !defined(sun)) || defined(ISC)) && \ 98629baa8cSmrg defined(SIOCGIFCONF) && !defined(USE_SIOCGLIFCONF) 99629baa8cSmrg# define SYSV_SIOCGIFCONF 100629baa8cSmrg#endif 101629baa8cSmrg 102629baa8cSmrg#ifdef HAVE_SYS_PARAM_H 103629baa8cSmrg#include <sys/param.h> 104629baa8cSmrg# ifdef BSD 105629baa8cSmrg# if (BSD >= 199103) 106629baa8cSmrg# define VARIABLE_IFREQ 107629baa8cSmrg# endif 108629baa8cSmrg# endif 109629baa8cSmrg#endif 110629baa8cSmrg 111629baa8cSmrg#ifdef __UNIXOS2__ 112629baa8cSmrg# define link rename 113629baa8cSmrgint chown(int a,int b,int c) {} 114629baa8cSmrg# include <io.h> 115629baa8cSmrg#endif 116629baa8cSmrg 117629baa8cSmrgstruct AuthProtocol { 118629baa8cSmrg unsigned short name_length; 119629baa8cSmrg char *name; 120629baa8cSmrg void (*InitAuth)(unsigned short len, char *name); 121629baa8cSmrg Xauth *(*GetAuth)(unsigned short len, char *name); 122629baa8cSmrg void (*GetXdmcpAuth)( 123629baa8cSmrg struct protoDisplay *pdpy, 124629baa8cSmrg unsigned short authorizationNameLen, 125629baa8cSmrg char *authorizationName); 126629baa8cSmrg int inited; 127629baa8cSmrg}; 128629baa8cSmrg 129629baa8cSmrgstatic struct AuthProtocol AuthProtocols[] = { 130629baa8cSmrg{ (unsigned short) 18, "MIT-MAGIC-COOKIE-1", 131629baa8cSmrg MitInitAuth, MitGetAuth, NULL 132629baa8cSmrg}, 133629baa8cSmrg#ifdef HASXDMAUTH 134629baa8cSmrg{ (unsigned short) 19, "XDM-AUTHORIZATION-1", 135629baa8cSmrg XdmInitAuth, XdmGetAuth, XdmGetXdmcpAuth, 136629baa8cSmrg}, 137629baa8cSmrg#endif 138629baa8cSmrg#ifdef SECURE_RPC 139629baa8cSmrg{ (unsigned short) 9, "SUN-DES-1", 140629baa8cSmrg SecureRPCInitAuth, SecureRPCGetAuth, NULL, 141629baa8cSmrg}, 142629baa8cSmrg#endif 143629baa8cSmrg#ifdef K5AUTH 144629baa8cSmrg{ (unsigned short) 14, "MIT-KERBEROS-5", 145629baa8cSmrg Krb5InitAuth, Krb5GetAuth, NULL, 146629baa8cSmrg}, 147629baa8cSmrg#endif 148629baa8cSmrg}; 149629baa8cSmrg 150629baa8cSmrg#define NUM_AUTHORIZATION (sizeof (AuthProtocols) / sizeof (AuthProtocols[0])) 151629baa8cSmrg 152629baa8cSmrgstatic struct AuthProtocol * 153629baa8cSmrgfindProtocol (unsigned short name_length, char *name) 154629baa8cSmrg{ 155629baa8cSmrg int i; 156629baa8cSmrg 157629baa8cSmrg for (i = 0; i < NUM_AUTHORIZATION; i++) 158629baa8cSmrg if (AuthProtocols[i].name_length == name_length && 159629baa8cSmrg memcmp(AuthProtocols[i].name, name, name_length) == 0) 160629baa8cSmrg { 161629baa8cSmrg return &AuthProtocols[i]; 162629baa8cSmrg } 163629baa8cSmrg return (struct AuthProtocol *) 0; 164629baa8cSmrg} 165629baa8cSmrg 166629baa8cSmrgint 167629baa8cSmrgValidAuthorization (unsigned short name_length, char *name) 168629baa8cSmrg{ 169629baa8cSmrg if (findProtocol (name_length, name)) 170629baa8cSmrg return TRUE; 171629baa8cSmrg return FALSE; 172629baa8cSmrg} 173629baa8cSmrg 174629baa8cSmrgstatic Xauth * 175629baa8cSmrgGenerateAuthorization (unsigned short name_length, char *name) 176629baa8cSmrg{ 177629baa8cSmrg struct AuthProtocol *a; 178629baa8cSmrg Xauth *auth = NULL; 179629baa8cSmrg int i; 180629baa8cSmrg 181629baa8cSmrg Debug ("GenerateAuthorization %*.*s\n", 182629baa8cSmrg name_length, name_length, name); 183629baa8cSmrg a = findProtocol (name_length, name); 184629baa8cSmrg if (a) 185629baa8cSmrg { 186629baa8cSmrg if (!a->inited) 187629baa8cSmrg { 188629baa8cSmrg (*a->InitAuth) (name_length, name); 189629baa8cSmrg a->inited = TRUE; 190629baa8cSmrg } 191629baa8cSmrg auth = (*a->GetAuth) (name_length, name); 192629baa8cSmrg if (auth) 193629baa8cSmrg { 194629baa8cSmrg Debug ("Got %p (%d %*.*s) ", auth, 195629baa8cSmrg auth->name_length, auth->name_length, 196629baa8cSmrg auth->name_length, auth->name); 197629baa8cSmrg for (i = 0; i < (int)auth->data_length; i++) 198629baa8cSmrg Debug (" %02x", auth->data[i] & 0xff); 199629baa8cSmrg Debug ("\n"); 200629baa8cSmrg } 201629baa8cSmrg else 202629baa8cSmrg Debug ("Got (null)\n"); 203629baa8cSmrg } 204629baa8cSmrg else 205629baa8cSmrg { 206629baa8cSmrg Debug ("Unknown authorization %*.*s\n", name_length, name_length, name); 207629baa8cSmrg } 208629baa8cSmrg return auth; 209629baa8cSmrg} 210629baa8cSmrg 211629baa8cSmrg#ifdef XDMCP 212629baa8cSmrg 213629baa8cSmrgvoid 214629baa8cSmrgSetProtoDisplayAuthorization ( 215629baa8cSmrg struct protoDisplay *pdpy, 216629baa8cSmrg unsigned short authorizationNameLen, 217629baa8cSmrg char *authorizationName) 218629baa8cSmrg{ 219629baa8cSmrg struct AuthProtocol *a; 220629baa8cSmrg Xauth *auth; 221629baa8cSmrg 222629baa8cSmrg a = findProtocol (authorizationNameLen, authorizationName); 223629baa8cSmrg pdpy->xdmcpAuthorization = pdpy->fileAuthorization = NULL; 224629baa8cSmrg if (a) 225629baa8cSmrg { 226629baa8cSmrg if (!a->inited) 227629baa8cSmrg { 228629baa8cSmrg (*a->InitAuth) (authorizationNameLen, authorizationName); 229629baa8cSmrg a->inited = TRUE; 230629baa8cSmrg } 231629baa8cSmrg if (a->GetXdmcpAuth) 232629baa8cSmrg { 233629baa8cSmrg (*a->GetXdmcpAuth) (pdpy, authorizationNameLen, authorizationName); 234629baa8cSmrg auth = pdpy->xdmcpAuthorization; 235629baa8cSmrg } 236629baa8cSmrg else 237629baa8cSmrg { 238629baa8cSmrg auth = (*a->GetAuth) (authorizationNameLen, authorizationName); 239629baa8cSmrg pdpy->fileAuthorization = auth; 240629baa8cSmrg pdpy->xdmcpAuthorization = NULL; 241629baa8cSmrg } 242629baa8cSmrg if (auth) 243629baa8cSmrg Debug ("Got %p (%d %*.*s)\n", auth, 244629baa8cSmrg auth->name_length, auth->name_length, 245629baa8cSmrg auth->name_length, auth->name); 246629baa8cSmrg else 247629baa8cSmrg Debug ("Got (null)\n"); 248629baa8cSmrg } 249629baa8cSmrg} 250629baa8cSmrg 251629baa8cSmrg#endif /* XDMCP */ 252629baa8cSmrg 253629baa8cSmrgvoid 254629baa8cSmrgCleanUpFileName (char *src, char *dst, int len) 255629baa8cSmrg{ 256629baa8cSmrg while (*src) { 257629baa8cSmrg if (--len <= 0) 258629baa8cSmrg break; 259629baa8cSmrg switch (*src & 0x7f) 260629baa8cSmrg { 261629baa8cSmrg case '/': 262629baa8cSmrg *dst++ = '_'; 263629baa8cSmrg break; 264629baa8cSmrg case '-': 265629baa8cSmrg *dst++ = '.'; 266629baa8cSmrg break; 267629baa8cSmrg default: 268629baa8cSmrg *dst++ = (*src & 0x7f); 269629baa8cSmrg } 270629baa8cSmrg ++src; 271629baa8cSmrg } 272629baa8cSmrg *dst = '\0'; 273629baa8cSmrg} 274629baa8cSmrg 275629baa8cSmrg/* Checks to see if specified directory exists, makes it if not 276629baa8cSmrg * Returns: 0 if already exists, 1 if created, < 0 if error occured 277629baa8cSmrg */ 278629baa8cSmrgstatic int 279629baa8cSmrgCheckServerAuthDir (const char *path, struct stat *statb, int mode) 280629baa8cSmrg{ 281629baa8cSmrg int r = stat(path, statb); 282629baa8cSmrg 283629baa8cSmrg if (r != 0) { 284629baa8cSmrg if (errno == ENOENT) { 285629baa8cSmrg r = mkdir(path, mode); 286629baa8cSmrg if (r < 0) { 287629baa8cSmrg LogError ("cannot make authentication directory %s: %s\n", 288629baa8cSmrg path, _SysErrorMsg (errno)); 289629baa8cSmrg } else { 290629baa8cSmrg r = 1; 291629baa8cSmrg } 292629baa8cSmrg } else { 293629baa8cSmrg LogError ("cannot access authentication directory %s: %s\n", 294629baa8cSmrg path, _SysErrorMsg (errno)); 295629baa8cSmrg } 296629baa8cSmrg } else { /* Directory already exists */ 297629baa8cSmrg if (!S_ISDIR(statb->st_mode)) { 298629baa8cSmrg LogError ("cannot make authentication directory %s: %s\n", 299629baa8cSmrg path, "file with that name already exists"); 300629baa8cSmrg return -1; 301629baa8cSmrg } 302629baa8cSmrg } 303629baa8cSmrg 304629baa8cSmrg return r; 305629baa8cSmrg} 306629baa8cSmrg 307629baa8cSmrgstatic char authdir1[] = "authdir"; 308629baa8cSmrgstatic char authdir2[] = "authfiles"; 309629baa8cSmrg 310629baa8cSmrgstatic int 311629baa8cSmrgMakeServerAuthFile (struct display *d, FILE ** file) 312629baa8cSmrg{ 313629baa8cSmrg int len; 314629baa8cSmrg#ifdef MAXNAMELEN 315629baa8cSmrg# define NAMELEN MAXNAMELEN 316629baa8cSmrg#else 317629baa8cSmrg# define NAMELEN 255 318629baa8cSmrg#endif 319629baa8cSmrg char cleanname[NAMELEN]; 320629baa8cSmrg int r; 321629baa8cSmrg#ifdef HAVE_MKSTEMP 322629baa8cSmrg int fd; 323629baa8cSmrg#endif 324629baa8cSmrg struct stat statb; 325629baa8cSmrg 326629baa8cSmrg *file = NULL; 327629baa8cSmrg 328629baa8cSmrg if (!d->authFile) { 329629baa8cSmrg if (d->clientAuthFile && *d->clientAuthFile) { 330629baa8cSmrg d->authFile = strdup(d->clientAuthFile); 331629baa8cSmrg if (!d->authFile) 332629baa8cSmrg return FALSE; 333629baa8cSmrg } else { 334629baa8cSmrg CleanUpFileName (d->name, cleanname, NAMELEN - 8); 335629baa8cSmrg 336629baa8cSmrg /* Make authDir if it doesn't already exist */ 337629baa8cSmrg r = CheckServerAuthDir(authDir, &statb, 0755); 338629baa8cSmrg if (r < 0) { 339629baa8cSmrg return FALSE; 340629baa8cSmrg } 341629baa8cSmrg 342629baa8cSmrg len = strlen (authDir) + strlen (authdir1) + strlen (authdir2) 343629baa8cSmrg + strlen (cleanname) + 14; 344629baa8cSmrg d->authFile = malloc (len); 345629baa8cSmrg if (!d->authFile) 346629baa8cSmrg return FALSE; 347629baa8cSmrg 348629baa8cSmrg snprintf (d->authFile, len, "%s/%s", authDir, authdir1); 349629baa8cSmrg r = CheckServerAuthDir(d->authFile, &statb, 0700); 350629baa8cSmrg if (r == 0) { 351629baa8cSmrg if (statb.st_uid != 0) 352629baa8cSmrg (void) chown(d->authFile, 0, statb.st_gid); 353629baa8cSmrg if ((statb.st_mode & 0077) != 0) 354629baa8cSmrg (void) chmod(d->authFile, statb.st_mode & 0700); 355629baa8cSmrg } else if (r < 0) { 356629baa8cSmrg free (d->authFile); 357629baa8cSmrg d->authFile = NULL; 358629baa8cSmrg return FALSE; 359629baa8cSmrg } 360629baa8cSmrg 361629baa8cSmrg snprintf (d->authFile, len, "%s/%s/%s", 362629baa8cSmrg authDir, authdir1, authdir2); 363629baa8cSmrg r = CheckServerAuthDir(d->authFile, &statb, 0700); 364629baa8cSmrg if (r < 0) { 365629baa8cSmrg free (d->authFile); 366629baa8cSmrg d->authFile = NULL; 367629baa8cSmrg return FALSE; 368629baa8cSmrg } 369629baa8cSmrg snprintf (d->authFile, len, "%s/%s/%s/A%s-XXXXXX", 370629baa8cSmrg authDir, authdir1, authdir2, cleanname); 371629baa8cSmrg#ifdef HAVE_MKSTEMP 372629baa8cSmrg fd = mkstemp (d->authFile); 373629baa8cSmrg if (fd < 0) { 374629baa8cSmrg LogError ("cannot make authentication file %s: %s\n", 375629baa8cSmrg d->authFile, _SysErrorMsg (errno)); 376629baa8cSmrg free (d->authFile); 377629baa8cSmrg d->authFile = NULL; 378629baa8cSmrg return FALSE; 379629baa8cSmrg } 380629baa8cSmrg 381629baa8cSmrg *file = fdopen(fd, "w"); 382629baa8cSmrg if (!*file) 383629baa8cSmrg (void) close (fd); 384629baa8cSmrg return TRUE; 385629baa8cSmrg#else 386629baa8cSmrg (void) mktemp (d->authFile); 387629baa8cSmrg#endif 388629baa8cSmrg } 389629baa8cSmrg } 390629baa8cSmrg 391629baa8cSmrg (void) unlink (d->authFile); 392629baa8cSmrg *file = fopen (d->authFile, "w"); 393629baa8cSmrg return TRUE; 394629baa8cSmrg} 395629baa8cSmrg 396629baa8cSmrgint 397629baa8cSmrgSaveServerAuthorizations ( 398629baa8cSmrg struct display *d, 399629baa8cSmrg Xauth **auths, 400629baa8cSmrg int count) 401629baa8cSmrg{ 402629baa8cSmrg FILE *auth_file; 403629baa8cSmrg mode_t mask; 404629baa8cSmrg int ret; 405629baa8cSmrg int i; 406629baa8cSmrg const char dummy_auth[] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" 407629baa8cSmrg "XXXXXXXXXXXXXXXXX"; /* 64 "X"s */ 408629baa8cSmrg int err = 0; 409629baa8cSmrg 410629baa8cSmrg mask = umask (0077); 411629baa8cSmrg ret = MakeServerAuthFile(d, &auth_file); 412629baa8cSmrg umask (mask); 413629baa8cSmrg if (!ret) 414629baa8cSmrg return FALSE; 415629baa8cSmrg if (!auth_file) { 416629baa8cSmrg LogError ("cannot open server authorization file %s: %s\n", 417629baa8cSmrg d->authFile, _SysErrorMsg (errno)); 418629baa8cSmrg ret = FALSE; 419629baa8cSmrg } 420629baa8cSmrg else 421629baa8cSmrg { 422629baa8cSmrg Debug ("File: %s auth: %p\n", d->authFile, auths); 423629baa8cSmrg ret = TRUE; 424629baa8cSmrg if (count == 0) 425629baa8cSmrg { 426629baa8cSmrg /* 427629baa8cSmrg * This is a crude hack to determine whether we really can 428629baa8cSmrg * write to the auth file even if we don't have real data 429629baa8cSmrg * to write right now. 430629baa8cSmrg */ 431629baa8cSmrg 432629baa8cSmrg /* 433629baa8cSmrg * Write garbage data to file to provoke ENOSPC and other 434629baa8cSmrg * errors. 435629baa8cSmrg */ 436629baa8cSmrg (void) fprintf (auth_file, "%s", dummy_auth); 437629baa8cSmrg (void) fflush (auth_file); 438629baa8cSmrg if (ferror (auth_file)) 439629baa8cSmrg { 440629baa8cSmrg err = errno; 441629baa8cSmrg ret = FALSE; 442629baa8cSmrg } 443629baa8cSmrg /* 444629baa8cSmrg * Rewind so that the garbage data is overwritten later. 445629baa8cSmrg */ 446629baa8cSmrg rewind(auth_file); 447629baa8cSmrg } 448629baa8cSmrg for (i = 0; i < count; i++) 449629baa8cSmrg { 450629baa8cSmrg /* 451629baa8cSmrg * User-based auths may not have data until 452629baa8cSmrg * a user logs in. In which case don't write 453629baa8cSmrg * to the auth file so xrdb and setup programs don't fail. 454629baa8cSmrg */ 455629baa8cSmrg if (auths[i]->data_length > 0) 456629baa8cSmrg if (!XauWriteAuth (auth_file, auths[i])) 457629baa8cSmrg { 458629baa8cSmrg Debug ("XauWriteAuth() failed\n"); 459629baa8cSmrg } 460629baa8cSmrg (void) fflush (auth_file); 461629baa8cSmrg if (ferror (auth_file)) 462629baa8cSmrg { 463629baa8cSmrg err = errno; 464629baa8cSmrg ret = FALSE; 465629baa8cSmrg } 466629baa8cSmrg } 467629baa8cSmrg /* 468629baa8cSmrg * XXX: This is not elegant, but stdio has no truncation function. 469629baa8cSmrg */ 470629baa8cSmrg if (ftruncate(fileno(auth_file), ftell(auth_file))) 471629baa8cSmrg { 472629baa8cSmrg Debug ("ftruncate() failed\n"); 473629baa8cSmrg } 474629baa8cSmrg fclose (auth_file); 475629baa8cSmrg 476629baa8cSmrg } 477629baa8cSmrg if (ret == FALSE) 478629baa8cSmrg { 479629baa8cSmrg LogError ("Cannot write to server authorization file %s%s%s\n", 480629baa8cSmrg d->authFile, 481629baa8cSmrg err ? ": " : "", 482629baa8cSmrg err ? _SysErrorMsg (errno) : ""); 483629baa8cSmrg free (d->authFile); 484629baa8cSmrg d->authFile = NULL; 485629baa8cSmrg } 486629baa8cSmrg return ret; 487629baa8cSmrg} 488629baa8cSmrg 489629baa8cSmrgvoid 490629baa8cSmrgSetLocalAuthorization (struct display *d) 491629baa8cSmrg{ 492629baa8cSmrg Xauth *auth, **auths; 493629baa8cSmrg int i, j; 494629baa8cSmrg 495629baa8cSmrg if (d->authorizations) 496629baa8cSmrg { 497629baa8cSmrg for (i = 0; i < d->authNum; i++) 498629baa8cSmrg XauDisposeAuth (d->authorizations[i]); 499629baa8cSmrg free (d->authorizations); 500629baa8cSmrg d->authorizations = (Xauth **) NULL; 501629baa8cSmrg d->authNum = 0; 502629baa8cSmrg } 503629baa8cSmrg if (!d->authNames) 504629baa8cSmrg return; 505629baa8cSmrg for (i = 0; d->authNames[i]; i++) 506629baa8cSmrg ; 507629baa8cSmrg d->authNameNum = i; 508629baa8cSmrg free (d->authNameLens); 509629baa8cSmrg d->authNameLens = malloc (d->authNameNum * sizeof (unsigned short)); 510629baa8cSmrg if (!d->authNameLens) 511629baa8cSmrg return; 512629baa8cSmrg for (i = 0; i < d->authNameNum; i++) 513629baa8cSmrg d->authNameLens[i] = strlen (d->authNames[i]); 514629baa8cSmrg auths = malloc (d->authNameNum * sizeof (Xauth *)); 515629baa8cSmrg if (!auths) 516629baa8cSmrg return; 517629baa8cSmrg j = 0; 518629baa8cSmrg for (i = 0; i < d->authNameNum; i++) 519629baa8cSmrg { 520629baa8cSmrg auth = GenerateAuthorization (d->authNameLens[i], d->authNames[i]); 521629baa8cSmrg if (auth) 522629baa8cSmrg auths[j++] = auth; 523629baa8cSmrg } 524629baa8cSmrg if (SaveServerAuthorizations (d, auths, j)) 525629baa8cSmrg { 526629baa8cSmrg d->authorizations = auths; 527629baa8cSmrg d->authNum = j; 528629baa8cSmrg } 529629baa8cSmrg else 530629baa8cSmrg { 531629baa8cSmrg for (i = 0; i < j; i++) 532629baa8cSmrg XauDisposeAuth (auths[i]); 533629baa8cSmrg free (auths); 534629baa8cSmrg } 535629baa8cSmrg} 536629baa8cSmrg 537629baa8cSmrg/* 538629baa8cSmrg * Set the authorization to use for xdm's initial connection 539629baa8cSmrg * to the X server. Cannot use user-based authorizations 540629baa8cSmrg * because no one has logged in yet, so we don't have any 541629baa8cSmrg * user credentials. 542629baa8cSmrg * Well, actually we could use SUN-DES-1 because we tell the server 543629baa8cSmrg * to allow root in. This is bogus and should be fixed. 544629baa8cSmrg */ 545629baa8cSmrgvoid 546629baa8cSmrgSetAuthorization (struct display *d) 547629baa8cSmrg{ 548629baa8cSmrg register Xauth **auth = d->authorizations; 549629baa8cSmrg int i; 550629baa8cSmrg 551629baa8cSmrg for (i = 0; i < d->authNum; i++) 552629baa8cSmrg { 553629baa8cSmrg if (auth[i]->name_length == 9 && 554629baa8cSmrg memcmp(auth[i]->name, "SUN-DES-1", 9) == 0) 555629baa8cSmrg continue; 556629baa8cSmrg if (auth[i]->name_length == 14 && 557629baa8cSmrg memcmp(auth[i]->name, "MIT-KERBEROS-5", 14) == 0) 558629baa8cSmrg continue; 559629baa8cSmrg XSetAuthorization (auth[i]->name, (int) auth[i]->name_length, 560629baa8cSmrg auth[i]->data, (int) auth[i]->data_length); 561629baa8cSmrg } 562629baa8cSmrg} 563629baa8cSmrg 564629baa8cSmrgstatic int 565629baa8cSmrgopenFiles (char *name, char *new_name, FILE **oldp, FILE **newp) 566629baa8cSmrg{ 567629baa8cSmrg mode_t mask; 568629baa8cSmrg int newfd; 569629baa8cSmrg 570629baa8cSmrg strcpy (new_name, name); 571629baa8cSmrg strcat (new_name, "-n"); 572629baa8cSmrg /* 573629baa8cSmrg * Set safe umask for file creation operations. 574629baa8cSmrg */ 575629baa8cSmrg mask = umask (0077); 576629baa8cSmrg /* 577629baa8cSmrg * Unlink the authorization file we intend to create, and then open 578629baa8cSmrg * it with O_CREAT | O_EXCL to avoid race-based symlink attacks. 579629baa8cSmrg */ 580629baa8cSmrg (void) unlink (new_name); 581629baa8cSmrg newfd = open (new_name, O_WRONLY | O_CREAT | O_EXCL, 0600); 582629baa8cSmrg if (newfd >= 0) 583629baa8cSmrg *newp = fdopen (newfd, "w"); 584629baa8cSmrg else 585629baa8cSmrg { 586629baa8cSmrg LogError ("Cannot create file %s: %s\n", new_name, 587629baa8cSmrg _SysErrorMsg (errno)); 588629baa8cSmrg *newp = NULL; 589629baa8cSmrg } 590629baa8cSmrg /* 591629baa8cSmrg * There are no more attempts to create files after this point; 592629baa8cSmrg * restore the original umask. 593629baa8cSmrg */ 594629baa8cSmrg (void) umask (mask); 595629baa8cSmrg if (!*newp) { 596629baa8cSmrg Debug ("can't open new file %s\n", new_name); 597629baa8cSmrg return 0; 598629baa8cSmrg } 599629baa8cSmrg if (!*oldp) 600629baa8cSmrg *oldp = fopen (name, "r"); 601629baa8cSmrg Debug ("opens succeeded %s %s\n", name, new_name); 602629baa8cSmrg return 1; 603629baa8cSmrg} 604629baa8cSmrg 605629baa8cSmrgstatic int 606629baa8cSmrgbinaryEqual (char *a, char *b, unsigned short len) 607629baa8cSmrg{ 608629baa8cSmrg while (len-- > 0) 609629baa8cSmrg if (*a++ != *b++) 610629baa8cSmrg return FALSE; 611629baa8cSmrg return TRUE; 612629baa8cSmrg} 613629baa8cSmrg 614629baa8cSmrgstatic void 615629baa8cSmrgdumpBytes (unsigned short len, char *data) 616629baa8cSmrg{ 617629baa8cSmrg unsigned short i; 618629baa8cSmrg 619629baa8cSmrg Debug ("%d: ", len); 620629baa8cSmrg for (i = 0; i < len; i++) 621629baa8cSmrg Debug ("%02x ", data[i] & 0377); 622629baa8cSmrg Debug ("\n"); 623629baa8cSmrg} 624629baa8cSmrg 625629baa8cSmrgstatic void 626629baa8cSmrgdumpAuth (Xauth *auth) 627629baa8cSmrg{ 628629baa8cSmrg Debug ("family: %d\n", auth->family); 629629baa8cSmrg Debug ("addr: "); 630629baa8cSmrg dumpBytes (auth->address_length, auth->address); 631629baa8cSmrg Debug ("number: "); 632629baa8cSmrg dumpBytes (auth->number_length, auth->number); 633629baa8cSmrg Debug ("name: "); 634629baa8cSmrg dumpBytes (auth->name_length, auth->name); 635629baa8cSmrg Debug ("data: "); 636629baa8cSmrg dumpBytes (auth->data_length, auth->data); 637629baa8cSmrg} 638629baa8cSmrg 639629baa8cSmrgstruct addrList { 640629baa8cSmrg unsigned short family; 641629baa8cSmrg unsigned short address_length; 642629baa8cSmrg char *address; 643629baa8cSmrg unsigned short number_length; 644629baa8cSmrg char *number; 645629baa8cSmrg unsigned short name_length; 646629baa8cSmrg char *name; 647629baa8cSmrg struct addrList *next; 648629baa8cSmrg}; 649629baa8cSmrg 650629baa8cSmrgstatic struct addrList *addrs; 651629baa8cSmrg 652629baa8cSmrgstatic void 653629baa8cSmrginitAddrs (void) 654629baa8cSmrg{ 655629baa8cSmrg addrs = NULL; 656629baa8cSmrg} 657629baa8cSmrg 658629baa8cSmrgstatic void 659629baa8cSmrgdoneAddrs (void) 660629baa8cSmrg{ 661629baa8cSmrg struct addrList *a, *n; 662629baa8cSmrg for (a = addrs; a; a = n) { 663629baa8cSmrg n = a->next; 664629baa8cSmrg free (a->address); 665629baa8cSmrg free (a->number); 666629baa8cSmrg free (a); 667629baa8cSmrg } 668629baa8cSmrg} 669629baa8cSmrg 670629baa8cSmrgstatic int checkEntry (Xauth *auth); 671629baa8cSmrg 672629baa8cSmrgstatic void 673629baa8cSmrgsaveEntry (Xauth *auth) 674629baa8cSmrg{ 675629baa8cSmrg struct addrList *new; 676629baa8cSmrg 677629baa8cSmrg new = malloc (sizeof (struct addrList)); 678629baa8cSmrg if (!new) { 679629baa8cSmrg LogOutOfMem ("saveEntry"); 680629baa8cSmrg return; 681629baa8cSmrg } 682629baa8cSmrg if ((new->address_length = auth->address_length) > 0) { 683629baa8cSmrg new->address = malloc (auth->address_length); 684629baa8cSmrg if (!new->address) { 685629baa8cSmrg LogOutOfMem ("saveEntry"); 686629baa8cSmrg free (new); 687629baa8cSmrg return; 688629baa8cSmrg } 689629baa8cSmrg memmove( new->address, auth->address, (int) auth->address_length); 690629baa8cSmrg } else 691629baa8cSmrg new->address = NULL; 692629baa8cSmrg if ((new->number_length = auth->number_length) > 0) { 693629baa8cSmrg new->number = malloc (auth->number_length); 694629baa8cSmrg if (!new->number) { 695629baa8cSmrg LogOutOfMem ("saveEntry"); 696629baa8cSmrg free (new->address); 697629baa8cSmrg free (new); 698629baa8cSmrg return; 699629baa8cSmrg } 700629baa8cSmrg memmove( new->number, auth->number, (int) auth->number_length); 701629baa8cSmrg } else 702629baa8cSmrg new->number = NULL; 703629baa8cSmrg if ((new->name_length = auth->name_length) > 0) { 704629baa8cSmrg new->name = malloc (auth->name_length); 705629baa8cSmrg if (!new->name) { 706629baa8cSmrg LogOutOfMem ("saveEntry"); 707629baa8cSmrg free (new->number); 708629baa8cSmrg free (new->address); 709629baa8cSmrg free (new); 710629baa8cSmrg return; 711629baa8cSmrg } 712629baa8cSmrg memmove( new->name, auth->name, (int) auth->name_length); 713629baa8cSmrg } else 714629baa8cSmrg new->name = NULL; 715629baa8cSmrg new->family = auth->family; 716629baa8cSmrg new->next = addrs; 717629baa8cSmrg addrs = new; 718629baa8cSmrg} 719629baa8cSmrg 720629baa8cSmrgstatic int 721629baa8cSmrgcheckEntry (Xauth *auth) 722629baa8cSmrg{ 723629baa8cSmrg struct addrList *a; 724629baa8cSmrg 725629baa8cSmrg for (a = addrs; a; a = a->next) { 726629baa8cSmrg if (a->family == auth->family && 727629baa8cSmrg a->address_length == auth->address_length && 728629baa8cSmrg binaryEqual (a->address, auth->address, auth->address_length) && 729629baa8cSmrg a->number_length == auth->number_length && 730629baa8cSmrg binaryEqual (a->number, auth->number, auth->number_length) && 731629baa8cSmrg a->name_length == auth->name_length && 732629baa8cSmrg binaryEqual (a->name, auth->name, auth->name_length)) 733629baa8cSmrg { 734629baa8cSmrg return 1; 735629baa8cSmrg } 736629baa8cSmrg } 737629baa8cSmrg return 0; 738629baa8cSmrg} 739629baa8cSmrg 740629baa8cSmrgstatic int doWrite; 741629baa8cSmrg 742629baa8cSmrgstatic void 743629baa8cSmrgwriteAuth (FILE *file, Xauth *auth) 744629baa8cSmrg{ 745629baa8cSmrg if (debugLevel >= 15) { /* normally too verbose */ 746629baa8cSmrg Debug ("writeAuth: doWrite = %d\n", doWrite); 747629baa8cSmrg dumpAuth (auth); /* does Debug only */ 748629baa8cSmrg } 749629baa8cSmrg if (doWrite) 750629baa8cSmrg XauWriteAuth (file, auth); 751629baa8cSmrg} 752629baa8cSmrg 753629baa8cSmrgstatic void 754629baa8cSmrgwriteAddr ( 755629baa8cSmrg int family, 756629baa8cSmrg int addr_length, 757629baa8cSmrg char *addr, 758629baa8cSmrg FILE *file, 759629baa8cSmrg Xauth *auth) 760629baa8cSmrg{ 761629baa8cSmrg auth->family = (unsigned short) family; 762629baa8cSmrg auth->address_length = addr_length; 763629baa8cSmrg auth->address = addr; 764629baa8cSmrg Debug ("writeAddr: writing and saving an entry\n"); 765629baa8cSmrg writeAuth (file, auth); 766629baa8cSmrg saveEntry (auth); 767629baa8cSmrg} 768629baa8cSmrg 769629baa8cSmrgstatic void 770629baa8cSmrgDefineLocal (FILE *file, Xauth *auth) 771629baa8cSmrg{ 772629baa8cSmrg char displayname[100]; 773629baa8cSmrg int len = _XGetHostname (displayname, sizeof(displayname)); 774629baa8cSmrg 775629baa8cSmrg/* Make sure this produces the same string as _XGetHostname in lib/X/XlibInt.c. 776629baa8cSmrg * Otherwise, Xau will not be able to find your cookies in the Xauthority file. 777629baa8cSmrg * 778629baa8cSmrg * Note: POSIX says that the ``nodename'' member of utsname does _not_ have 779629baa8cSmrg * to have sufficient information for interfacing to the network, 780629baa8cSmrg * and so, you may be better off using gethostname (if it exists). 781629baa8cSmrg */ 782629baa8cSmrg 783629baa8cSmrg#if defined(hpux) 784629baa8cSmrg /* 785629baa8cSmrg * For HP-UX, HP's Xlib expects a fully-qualified domain name, which 786629baa8cSmrg * is achieved by using gethostname(). For compatability, we must 787629baa8cSmrg * also still create the entry using uname(). 788629baa8cSmrg */ 789629baa8cSmrg char tmp_displayname[100]; 790629baa8cSmrg struct utsname name; 791629baa8cSmrg 792629baa8cSmrg tmp_displayname[0] = 0; 793629baa8cSmrg uname(&name); 794629baa8cSmrg snprintf(tmp_displayname, sizeof(tmp_displayname), "%s", name.nodename); 795629baa8cSmrg writeAddr (FamilyLocal, strlen (tmp_displayname), tmp_displayname, 796629baa8cSmrg file, auth); 797629baa8cSmrg 798629baa8cSmrg /* 799629baa8cSmrg * If _XGetHostname() returned the same value as uname(), don't 800629baa8cSmrg * write a duplicate entry. 801629baa8cSmrg */ 802629baa8cSmrg if (strcmp (displayname, tmp_displayname)) 803629baa8cSmrg#endif 804629baa8cSmrg 805629baa8cSmrg writeAddr (FamilyLocal, len, displayname, file, auth); 806629baa8cSmrg} 807629baa8cSmrg 808629baa8cSmrg#ifdef HAVE_GETIFADDRS 809629baa8cSmrg# include <ifaddrs.h> 810629baa8cSmrg 811629baa8cSmrgstatic void 812629baa8cSmrgDefineSelf(int fd, FILE *file, Xauth *auth) 813629baa8cSmrg{ 814629baa8cSmrg struct ifaddrs *ifap, *ifr; 815629baa8cSmrg char *addr; 816629baa8cSmrg int family, len; 817629baa8cSmrg 818629baa8cSmrg Debug("DefineSelf\n"); 819629baa8cSmrg if (getifaddrs(&ifap) < 0) 820629baa8cSmrg return; 821629baa8cSmrg for (ifr = ifap; ifr != NULL; ifr = ifr->ifa_next) { 822629baa8cSmrg len = sizeof(*(ifr->ifa_addr)); 823629baa8cSmrg family = ConvertAddr((XdmcpNetaddr)(ifr->ifa_addr), &len, &addr); 824629baa8cSmrg if (family == -1 || family == FamilyLocal) 825629baa8cSmrg continue; 826629baa8cSmrg /* 827629baa8cSmrg * don't write out 'localhost' entries, as 828629baa8cSmrg * they may conflict with other local entries. 829629baa8cSmrg * DefineLocal will always be called to add 830629baa8cSmrg * the local entry anyway, so this one can 831629baa8cSmrg * be tossed. 832629baa8cSmrg */ 833629baa8cSmrg if (family == FamilyInternet && len == 4 && addr[0] == 127) 834629baa8cSmrg { 835629baa8cSmrg Debug ("Skipping localhost address\n"); 836629baa8cSmrg continue; 837629baa8cSmrg } 838629baa8cSmrg# if defined(IPv6) && defined(AF_INET6) 839629baa8cSmrg if(family == FamilyInternet6) { 840629baa8cSmrg if (IN6_IS_ADDR_LOOPBACK(((struct in6_addr *)addr))) { 841629baa8cSmrg Debug ("Skipping IPv6 localhost address\n"); 842629baa8cSmrg continue; 843629baa8cSmrg } 844629baa8cSmrg /* Also skip XDM-AUTHORIZATION-1 */ 845629baa8cSmrg if (auth->name_length == 19 && 846629baa8cSmrg strcmp(auth->name, "XDM-AUTHORIZATION-1") == 0) { 847629baa8cSmrg Debug ("Skipping IPv6 XDM-AUTHORIZATION-1\n"); 848629baa8cSmrg continue; 849629baa8cSmrg } 850629baa8cSmrg } 851629baa8cSmrg# endif 852629baa8cSmrg writeAddr(family, len, addr, file, auth); 853629baa8cSmrg } 854629baa8cSmrg freeifaddrs(ifap); 855629baa8cSmrg Debug("DefineSelf done\n"); 856629baa8cSmrg} 857629baa8cSmrg#else /* GETIFADDRS */ 858629baa8cSmrg 859629baa8cSmrg# ifdef SYSV_SIOCGIFCONF 860629baa8cSmrg 861629baa8cSmrg/* Deal with different SIOCGIFCONF ioctl semantics on SYSV, SVR4 */ 862629baa8cSmrg 863629baa8cSmrgstatic int 864629baa8cSmrgifioctl (int fd, int cmd, char *arg) 865629baa8cSmrg{ 866629baa8cSmrg struct strioctl ioc; 867629baa8cSmrg int ret; 868629baa8cSmrg 869629baa8cSmrg bzero((char *) &ioc, sizeof(ioc)); 870629baa8cSmrg ioc.ic_cmd = cmd; 871629baa8cSmrg ioc.ic_timout = 0; 872629baa8cSmrg if (cmd == SIOCGIFCONF) 873629baa8cSmrg { 874629baa8cSmrg ioc.ic_len = ((struct ifconf *) arg)->ifc_len; 875629baa8cSmrg ioc.ic_dp = ((struct ifconf *) arg)->ifc_buf; 876629baa8cSmrg# ifdef ISC 877629baa8cSmrg /* SIOCGIFCONF is somewhat brain damaged on ISC. The argument 878629baa8cSmrg * buffer must contain the ifconf structure as header. Ifc_req 879629baa8cSmrg * is also not a pointer but a one element array of ifreq 880629baa8cSmrg * structures. On return this array is extended by enough 881629baa8cSmrg * ifreq fields to hold all interfaces. The return buffer length 882629baa8cSmrg * is placed in the buffer header. 883629baa8cSmrg */ 884629baa8cSmrg ((struct ifconf *) ioc.ic_dp)->ifc_len = 885629baa8cSmrg ioc.ic_len - sizeof(struct ifconf); 886629baa8cSmrg# endif 887629baa8cSmrg } 888629baa8cSmrg else 889629baa8cSmrg { 890629baa8cSmrg ioc.ic_len = sizeof(struct ifreq); 891629baa8cSmrg ioc.ic_dp = arg; 892629baa8cSmrg } 893629baa8cSmrg ret = ioctl(fd, I_STR, (char *) &ioc); 894629baa8cSmrg if (ret >= 0 && cmd == SIOCGIFCONF) 895629baa8cSmrg# ifdef SVR4 896629baa8cSmrg ((struct ifconf *) arg)->ifc_len = ioc.ic_len; 897629baa8cSmrg# endif 898629baa8cSmrg# ifdef ISC 899629baa8cSmrg { 900629baa8cSmrg ((struct ifconf *) arg)->ifc_len = 901629baa8cSmrg ((struct ifconf *)ioc.ic_dp)->ifc_len; 902629baa8cSmrg ((struct ifconf *) arg)->ifc_buf = 903629baa8cSmrg (caddr_t)((struct ifconf *)ioc.ic_dp)->ifc_req; 904629baa8cSmrg } 905629baa8cSmrg# endif 906629baa8cSmrg return(ret); 907629baa8cSmrg} 908629baa8cSmrg# else /* SYSV_SIOCGIFCONF */ 909629baa8cSmrg# define ifioctl ioctl 910629baa8cSmrg# endif /* SYSV_SIOCGIFCONF */ 911629baa8cSmrg 912629baa8cSmrg# if defined(STREAMSCONN) && !defined(SYSV_SIOCGIFCONF) && !defined(NCR) 913629baa8cSmrg 914629baa8cSmrg# include <tiuser.h> 915629baa8cSmrg 916629baa8cSmrg/* Define this host for access control. Find all the hosts the OS knows about 917629baa8cSmrg * for this fd and add them to the selfhosts list. 918629baa8cSmrg * TLI version, written without sufficient documentation. 919629baa8cSmrg */ 920629baa8cSmrgstatic void 921629baa8cSmrgDefineSelf (int fd, FILE *file, Xauth *auth) 922629baa8cSmrg{ 923629baa8cSmrg struct netbuf netb; 924629baa8cSmrg char addrret[1024]; /* easier than t_alloc */ 925629baa8cSmrg 926629baa8cSmrg netb.maxlen = sizeof(addrret); 927629baa8cSmrg netb.buf = addrret; 928629baa8cSmrg if (t_getname (fd, &netb, LOCALNAME) == -1) 929629baa8cSmrg t_error ("t_getname"); 930629baa8cSmrg /* what a kludge */ 931629baa8cSmrg writeAddr (FamilyInternet, 4, netb.buf+4, file, auth); 932629baa8cSmrg} 933629baa8cSmrg 934629baa8cSmrg# else 935629baa8cSmrg 936629baa8cSmrg# ifdef WINTCP /* NCR with Wollongong TCP */ 937629baa8cSmrg 938629baa8cSmrg# include <sys/un.h> 939629baa8cSmrg# include <stropts.h> 940629baa8cSmrg# include <tiuser.h> 941629baa8cSmrg 942629baa8cSmrg# include <sys/stream.h> 943629baa8cSmrg# include <net/if.h> 944629baa8cSmrg# include <netinet/ip.h> 945629baa8cSmrg# include <netinet/ip_var.h> 946629baa8cSmrg# include <netinet/in.h> 947629baa8cSmrg# include <netinet/in_var.h> 948629baa8cSmrg 949629baa8cSmrgstatic void 950629baa8cSmrgDefineSelf (int fd, FILE *file, Xauth *auth) 951629baa8cSmrg{ 952629baa8cSmrg /* 953629baa8cSmrg * The Wollongong drivers used by NCR SVR4/MP-RAS don't understand the 954629baa8cSmrg * socket IO calls that most other drivers seem to like. Because of 955629baa8cSmrg * this, this routine must be special cased for NCR. Eventually, 956629baa8cSmrg * this will be cleared up. 957629baa8cSmrg */ 958629baa8cSmrg 959629baa8cSmrg struct ipb ifnet; 960629baa8cSmrg struct in_ifaddr ifaddr; 961629baa8cSmrg struct strioctl str; 962629baa8cSmrg unsigned char *addr; 963629baa8cSmrg int len, ipfd; 964629baa8cSmrg 965629baa8cSmrg if ((ipfd = open ("/dev/ip", O_RDWR, 0 )) < 0) 966629baa8cSmrg LogError ("cannot get interface configuration; cannot open /dev/ip: " 967629baa8cSmrg "%s\n", _SysErrorMsg (errno)); 968629baa8cSmrg 969629baa8cSmrg /* Indicate that we want to start at the begining */ 970629baa8cSmrg ifnet.ib_next = (struct ipb *) 1; 971629baa8cSmrg 972629baa8cSmrg while (ifnet.ib_next) 973629baa8cSmrg { 974629baa8cSmrg str.ic_cmd = IPIOC_GETIPB; 975629baa8cSmrg str.ic_timout = 0; 976629baa8cSmrg str.ic_len = sizeof (struct ipb); 977629baa8cSmrg str.ic_dp = (char *) &ifnet; 978629baa8cSmrg 979629baa8cSmrg if (ioctl (ipfd, (int) I_STR, (char *) &str) < 0) 980629baa8cSmrg { 981629baa8cSmrg LogError ("cannot get interface configuration; ioctl failed: %s\n", 982629baa8cSmrg _SysErrorMsg (errno)); 983629baa8cSmrg close (ipfd); 984629baa8cSmrg } 985629baa8cSmrg 986629baa8cSmrg ifaddr.ia_next = (struct in_ifaddr *) ifnet.if_addrlist; 987629baa8cSmrg str.ic_cmd = IPIOC_GETINADDR; 988629baa8cSmrg str.ic_timout = 0; 989629baa8cSmrg str.ic_len = sizeof (struct in_ifaddr); 990629baa8cSmrg str.ic_dp = (char *) &ifaddr; 991629baa8cSmrg 992629baa8cSmrg if (ioctl (ipfd, (int) I_STR, (char *) &str) < 0) 993629baa8cSmrg { 994629baa8cSmrg LogError ("cannot get interface configuration; ioctl failed: %s\n", 995629baa8cSmrg _SysErrorMsg (errno)); 996629baa8cSmrg close (ipfd); 997629baa8cSmrg } 998629baa8cSmrg 999629baa8cSmrg /* 1000629baa8cSmrg * Ignore the 127.0.0.1 entry. 1001629baa8cSmrg */ 1002629baa8cSmrg if (IA_SIN(&ifaddr)->sin_addr.s_addr == htonl(0x7f000001) ) 1003629baa8cSmrg continue; 1004629baa8cSmrg 1005629baa8cSmrg writeAddr (FamilyInternet, 4, (char *)&(IA_SIN(&ifaddr)->sin_addr), file, auth); 1006629baa8cSmrg 1007629baa8cSmrg } 1008629baa8cSmrg close(ipfd); 1009629baa8cSmrg} 1010629baa8cSmrg 1011629baa8cSmrg# else /* WINTCP */ 1012629baa8cSmrg 1013629baa8cSmrg# if defined(SIOCGIFCONF) || defined (USE_SIOCGLIFCONF) 1014629baa8cSmrg 1015629baa8cSmrg# ifdef USE_SIOCGLIFCONF 1016629baa8cSmrg# define ifr_type struct lifreq 1017629baa8cSmrg# else 1018629baa8cSmrg# define ifr_type struct ifreq 1019629baa8cSmrg# endif 1020629baa8cSmrg 1021629baa8cSmrg/* Handle variable length ifreq in BNR2 and later */ 1022629baa8cSmrg# ifdef VARIABLE_IFREQ 1023629baa8cSmrg# define ifr_size(p) (sizeof (struct ifreq) + \ 1024629baa8cSmrg (p->ifr_addr.sa_len > sizeof (p->ifr_addr) ? \ 1025629baa8cSmrg p->ifr_addr.sa_len - sizeof (p->ifr_addr) : 0)) 1026629baa8cSmrg# else 1027629baa8cSmrg# define ifr_size(p) (sizeof (ifr_type)) 1028629baa8cSmrg# endif 1029629baa8cSmrg 1030629baa8cSmrg/* Define this host for access control. Find all the hosts the OS knows about 1031629baa8cSmrg * for this fd and add them to the selfhosts list. 1032629baa8cSmrg */ 1033629baa8cSmrgstatic void 1034629baa8cSmrgDefineSelf (int fd, FILE *file, Xauth *auth) 1035629baa8cSmrg{ 1036629baa8cSmrg char buf[2048], *cp, *cplim; 1037629baa8cSmrg int len; 1038629baa8cSmrg char *addr; 1039629baa8cSmrg int family; 1040629baa8cSmrg register ifr_type *ifr; 1041629baa8cSmrg# ifdef USE_SIOCGLIFCONF 1042629baa8cSmrg void * bufptr = buf; 1043629baa8cSmrg size_t buflen = sizeof(buf); 1044629baa8cSmrg struct lifconf ifc; 1045629baa8cSmrg# ifdef SIOCGLIFNUM 1046629baa8cSmrg struct lifnum ifn; 1047629baa8cSmrg# endif 1048629baa8cSmrg# else 1049629baa8cSmrg struct ifconf ifc; 1050629baa8cSmrg# endif 1051629baa8cSmrg 1052629baa8cSmrg# if defined(SIOCGLIFNUM) && defined(SIOCGLIFCONF) 1053629baa8cSmrg ifn.lifn_family = AF_UNSPEC; 1054629baa8cSmrg ifn.lifn_flags = 0; 1055629baa8cSmrg if (ioctl (fd, (int) SIOCGLIFNUM, (char *) &ifn) < 0) 1056629baa8cSmrg LogError ("Failed getting interface count"); 1057629baa8cSmrg if (buflen < (ifn.lifn_count * sizeof(struct lifreq))) { 1058629baa8cSmrg buflen = ifn.lifn_count * sizeof(struct lifreq); 1059629baa8cSmrg bufptr = malloc(buflen); 1060629baa8cSmrg } 1061629baa8cSmrg# endif 1062629baa8cSmrg 1063629baa8cSmrg# ifdef USE_SIOCGLIFCONF 1064629baa8cSmrg ifc.lifc_family = AF_UNSPEC; 1065629baa8cSmrg ifc.lifc_flags = 0; 1066629baa8cSmrg ifc.lifc_len = buflen; 1067629baa8cSmrg ifc.lifc_buf = bufptr; 1068629baa8cSmrg 1069629baa8cSmrg# define IFC_IOCTL_REQ SIOCGLIFCONF 1070629baa8cSmrg# define IFC_IFC_REQ ifc.lifc_req 1071629baa8cSmrg# define IFC_IFC_LEN ifc.lifc_len 1072629baa8cSmrg# define IFR_IFR_ADDR ifr->lifr_addr 1073629baa8cSmrg# define IFR_IFR_NAME ifr->lifr_name 1074629baa8cSmrg 1075629baa8cSmrg# else 1076629baa8cSmrg ifc.ifc_len = sizeof (buf); 1077629baa8cSmrg ifc.ifc_buf = buf; 1078629baa8cSmrg 1079629baa8cSmrg# define IFC_IOCTL_REQ SIOCGIFCONF 1080629baa8cSmrg# ifdef ISC 1081629baa8cSmrg# define IFC_IFC_REQ (struct ifreq *) ifc.ifc_buf 1082629baa8cSmrg# else 1083629baa8cSmrg# define IFC_IFC_REQ ifc.ifc_req 1084629baa8cSmrg# endif 1085629baa8cSmrg# define IFC_IFC_LEN ifc.ifc_len 1086629baa8cSmrg# define IFR_IFR_ADDR ifr->ifr_addr 1087629baa8cSmrg# define IFR_IFR_NAME ifr->ifr_name 1088629baa8cSmrg# endif 1089629baa8cSmrg 1090629baa8cSmrg if (ifioctl (fd, IFC_IOCTL_REQ, (char *) &ifc) < 0) { 1091629baa8cSmrg LogError ("Trouble getting network interface configuration"); 1092629baa8cSmrg 1093629baa8cSmrg# ifdef USE_SIOCGLIFCONF 1094629baa8cSmrg if (bufptr != buf) { 1095629baa8cSmrg free(bufptr); 1096629baa8cSmrg } 1097629baa8cSmrg# endif 1098629baa8cSmrg return; 1099629baa8cSmrg } 1100629baa8cSmrg 1101629baa8cSmrg cplim = (char *) IFC_IFC_REQ + IFC_IFC_LEN; 1102629baa8cSmrg 1103629baa8cSmrg for (cp = (char *) IFC_IFC_REQ; cp < cplim; cp += ifr_size (ifr)) 1104629baa8cSmrg { 1105629baa8cSmrg ifr = (ifr_type *) cp; 1106629baa8cSmrg# ifdef DNETCONN 1107629baa8cSmrg /* 1108629baa8cSmrg * this is ugly but SIOCGIFCONF returns decnet addresses in 1109629baa8cSmrg * a different form from other decnet calls 1110629baa8cSmrg */ 1111629baa8cSmrg if (IFR_IFR_ADDR.sa_family == AF_DECnet) { 1112629baa8cSmrg len = sizeof (struct dn_naddr); 1113629baa8cSmrg addr = (char *)ifr->ifr_addr.sa_data; 1114629baa8cSmrg family = FamilyDECnet; 1115629baa8cSmrg } else 1116629baa8cSmrg# endif 1117629baa8cSmrg { 1118629baa8cSmrg family = ConvertAddr ((XdmcpNetaddr) &IFR_IFR_ADDR, &len, &addr); 1119629baa8cSmrg if (family < 0) 1120629baa8cSmrg continue; 1121629baa8cSmrg 1122629baa8cSmrg if (len == 0) 1123629baa8cSmrg { 1124629baa8cSmrg Debug ("Skipping zero length address\n"); 1125629baa8cSmrg continue; 1126629baa8cSmrg } 1127629baa8cSmrg /* 1128629baa8cSmrg * don't write out 'localhost' entries, as 1129629baa8cSmrg * they may conflict with other local entries. 1130629baa8cSmrg * DefineLocal will always be called to add 1131629baa8cSmrg * the local entry anyway, so this one can 1132629baa8cSmrg * be tossed. 1133629baa8cSmrg */ 1134629baa8cSmrg if (family == FamilyInternet && len == 4 && 1135629baa8cSmrg addr[0] == 127 && addr[1] == 0 && 1136629baa8cSmrg addr[2] == 0 && addr[3] == 1) 1137629baa8cSmrg { 1138629baa8cSmrg Debug ("Skipping localhost address\n"); 1139629baa8cSmrg continue; 1140629baa8cSmrg } 1141629baa8cSmrg# if defined(IPv6) && defined(AF_INET6) 1142629baa8cSmrg if(family == FamilyInternet6) { 1143629baa8cSmrg if (IN6_IS_ADDR_LOOPBACK(((struct in6_addr *)addr))) { 1144629baa8cSmrg Debug ("Skipping IPv6 localhost address\n"); 1145629baa8cSmrg continue; 1146629baa8cSmrg } 1147629baa8cSmrg /* Also skip XDM-AUTHORIZATION-1 */ 1148629baa8cSmrg if (auth->name_length == 19 && 1149629baa8cSmrg strcmp(auth->name, "XDM-AUTHORIZATION-1") == 0) { 1150629baa8cSmrg Debug ("Skipping IPv6 XDM-AUTHORIZATION-1\n"); 1151629baa8cSmrg continue; 1152629baa8cSmrg } 1153629baa8cSmrg } 1154629baa8cSmrg# endif 1155629baa8cSmrg } 1156629baa8cSmrg Debug ("DefineSelf: write network address, length %d\n", len); 1157629baa8cSmrg writeAddr (family, len, addr, file, auth); 1158629baa8cSmrg } 1159629baa8cSmrg} 1160629baa8cSmrg 1161629baa8cSmrg# else /* SIOCGIFCONF */ 1162629baa8cSmrg 1163629baa8cSmrg/* Define this host for access control. Find all the hosts the OS knows about 1164629baa8cSmrg * for this fd and add them to the selfhosts list. 1165629baa8cSmrg */ 1166629baa8cSmrgstatic void 1167629baa8cSmrgDefineSelf (int fd, int file, int auth) 1168629baa8cSmrg{ 1169629baa8cSmrg register int n; 1170629baa8cSmrg int len; 1171629baa8cSmrg caddr_t addr; 1172629baa8cSmrg int family; 1173629baa8cSmrg 1174629baa8cSmrg struct utsname name; 1175629baa8cSmrg register struct hostent *hp; 1176629baa8cSmrg 1177629baa8cSmrg union { 1178629baa8cSmrg struct sockaddr sa; 1179629baa8cSmrg struct sockaddr_in in; 1180629baa8cSmrg } saddr; 1181629baa8cSmrg 1182629baa8cSmrg struct sockaddr_in *inetaddr; 1183629baa8cSmrg 1184629baa8cSmrg /* hpux: 1185629baa8cSmrg * Why not use gethostname()? Well, at least on my system, I've had to 1186629baa8cSmrg * make an ugly kernel patch to get a name longer than 8 characters, and 1187629baa8cSmrg * uname() lets me access to the whole string (it smashes release, you 1188629baa8cSmrg * see), whereas gethostname() kindly truncates it for me. 1189629baa8cSmrg */ 1190629baa8cSmrg uname(&name); 1191629baa8cSmrg hp = gethostbyname (name.nodename); 1192629baa8cSmrg if (hp != NULL) { 1193629baa8cSmrg saddr.sa.sa_family = hp->h_addrtype; 1194629baa8cSmrg inetaddr = (struct sockaddr_in *) (&(saddr.sa)); 1195629baa8cSmrg memmove( (char *) &(inetaddr->sin_addr), (char *) hp->h_addr, (int) hp->h_length); 1196629baa8cSmrg family = ConvertAddr ( &(saddr.sa), &len, &addr); 1197629baa8cSmrg if ( family >= 0) { 1198629baa8cSmrg writeAddr (FamilyInternet, sizeof (inetaddr->sin_addr), 1199629baa8cSmrg (char *) (&inetaddr->sin_addr), file, auth); 1200629baa8cSmrg } 1201629baa8cSmrg } 1202629baa8cSmrg} 1203629baa8cSmrg 1204629baa8cSmrg 1205629baa8cSmrg# endif /* SIOCGIFCONF else */ 1206629baa8cSmrg# endif /* WINTCP else */ 1207629baa8cSmrg# endif /* STREAMSCONN && !SYSV_SIOCGIFCONF else */ 1208629baa8cSmrg#endif /* HAVE_GETIFADDRS */ 1209629baa8cSmrg 1210629baa8cSmrgstatic void 1211629baa8cSmrgsetAuthNumber (Xauth *auth, char *name) 1212629baa8cSmrg{ 1213629baa8cSmrg char *colon; 1214629baa8cSmrg char *dot, *number; 1215629baa8cSmrg 1216629baa8cSmrg Debug ("setAuthNumber %s\n", name); 1217629baa8cSmrg colon = strrchr(name, ':'); 1218629baa8cSmrg if (colon) { 1219629baa8cSmrg ++colon; 1220629baa8cSmrg dot = strchr(colon, '.'); 1221629baa8cSmrg if (dot) 1222629baa8cSmrg auth->number_length = dot - colon; 1223629baa8cSmrg else 1224629baa8cSmrg auth->number_length = strlen (colon); 1225629baa8cSmrg number = malloc (auth->number_length + 1); 1226629baa8cSmrg if (number) { 1227629baa8cSmrg strncpy (number, colon, auth->number_length); 1228629baa8cSmrg number[auth->number_length] = '\0'; 1229629baa8cSmrg } else { 1230629baa8cSmrg LogOutOfMem ("setAuthNumber"); 1231629baa8cSmrg auth->number_length = 0; 1232629baa8cSmrg } 1233629baa8cSmrg auth->number = number; 1234629baa8cSmrg Debug ("setAuthNumber: %s\n", number); 1235629baa8cSmrg } 1236629baa8cSmrg} 1237629baa8cSmrg 1238629baa8cSmrgstatic void 1239629baa8cSmrgwriteLocalAuth (FILE *file, Xauth *auth, char *name) 1240629baa8cSmrg{ 1241629baa8cSmrg int fd; 1242629baa8cSmrg 1243629baa8cSmrg Debug ("writeLocalAuth: %s %.*s\n", name, auth->name_length, auth->name); 1244629baa8cSmrg setAuthNumber (auth, name); 1245629baa8cSmrg#ifdef STREAMSCONN 1246629baa8cSmrg fd = t_open ("/dev/tcp", O_RDWR, 0); 1247629baa8cSmrg t_bind(fd, NULL, NULL); 1248629baa8cSmrg DefineSelf (fd, file, auth); 1249629baa8cSmrg t_unbind (fd); 1250629baa8cSmrg t_close (fd); 1251629baa8cSmrg#endif 1252629baa8cSmrg#ifdef TCPCONN 1253629baa8cSmrg# if defined(IPv6) && defined(AF_INET6) 1254629baa8cSmrg fd = socket (AF_INET6, SOCK_STREAM, 0); 1255629baa8cSmrg if (fd < 0) 1256629baa8cSmrg# endif 1257629baa8cSmrg fd = socket (AF_INET, SOCK_STREAM, 0); 1258629baa8cSmrg DefineSelf (fd, file, auth); 1259629baa8cSmrg close (fd); 1260629baa8cSmrg#endif 1261629baa8cSmrg#ifdef DNETCONN 1262629baa8cSmrg fd = socket (AF_DECnet, SOCK_STREAM, 0); 1263629baa8cSmrg DefineSelf (fd, file, auth); 1264629baa8cSmrg close (fd); 1265629baa8cSmrg#endif 1266629baa8cSmrg DefineLocal (file, auth); 1267629baa8cSmrg} 1268629baa8cSmrg 1269629baa8cSmrg#ifdef XDMCP 1270629baa8cSmrg 1271629baa8cSmrgstatic void 1272629baa8cSmrgwriteRemoteAuth (FILE *file, Xauth *auth, XdmcpNetaddr peer, int peerlen, char *name) 1273629baa8cSmrg{ 1274629baa8cSmrg int family = FamilyLocal; 1275629baa8cSmrg char *addr; 1276629baa8cSmrg 1277629baa8cSmrg Debug ("writeRemoteAuth: %s %.*s\n", name, auth->name_length, auth->name); 1278629baa8cSmrg if (!peer || peerlen < 2) 1279629baa8cSmrg return; 1280629baa8cSmrg setAuthNumber (auth, name); 1281629baa8cSmrg family = ConvertAddr (peer, &peerlen, &addr); 1282629baa8cSmrg Debug ("writeRemoteAuth: family %d\n", family); 1283629baa8cSmrg if (family != FamilyLocal) 1284629baa8cSmrg { 1285629baa8cSmrg Debug ("writeRemoteAuth: %d, %d, %x\n", 1286629baa8cSmrg family, peerlen, *(int *)addr); 1287629baa8cSmrg writeAddr (family, peerlen, addr, file, auth); 1288629baa8cSmrg } 1289629baa8cSmrg else 1290629baa8cSmrg { 1291629baa8cSmrg writeLocalAuth (file, auth, name); 1292629baa8cSmrg } 1293629baa8cSmrg} 1294629baa8cSmrg 1295629baa8cSmrg#endif /* XDMCP */ 1296629baa8cSmrg 1297629baa8cSmrgvoid 1298629baa8cSmrgSetUserAuthorization (struct display *d, struct verify_info *verify) 1299629baa8cSmrg{ 1300629baa8cSmrg FILE *old = NULL, *new; 1301629baa8cSmrg char home_name[1024], backup_name[1024], new_name[1024]; 1302629baa8cSmrg char *name = NULL; 1303629baa8cSmrg char *home; 1304629baa8cSmrg char *envname = NULL; 1305629baa8cSmrg int lockStatus; 1306629baa8cSmrg Xauth *entry, **auths; 1307629baa8cSmrg int setenv = 0; 1308629baa8cSmrg struct stat statb; 1309629baa8cSmrg int i; 1310629baa8cSmrg int magicCookie; 1311629baa8cSmrg int data_len; 1312629baa8cSmrg#ifdef HAVE_MKSTEMP 1313629baa8cSmrg int fd; 1314629baa8cSmrg#endif 1315629baa8cSmrg 1316629baa8cSmrg Debug ("SetUserAuthorization\n"); 1317629baa8cSmrg auths = d->authorizations; 1318629baa8cSmrg if (auths) { 1319629baa8cSmrg home = getEnv (verify->userEnviron, "HOME"); 1320629baa8cSmrg lockStatus = LOCK_ERROR; 1321629baa8cSmrg if (home) { 1322629baa8cSmrg snprintf (home_name, sizeof(home_name), "%s/.Xauthority", home); 1323629baa8cSmrg Debug ("XauLockAuth %s\n", home_name); 1324629baa8cSmrg lockStatus = XauLockAuth (home_name, 1, 2, 10); 1325629baa8cSmrg Debug ("Lock is %d\n", lockStatus); 1326629baa8cSmrg if (lockStatus == LOCK_SUCCESS) { 1327629baa8cSmrg if (openFiles (home_name, new_name, &old, &new) 1328629baa8cSmrg && (old != NULL) && (new != NULL)) { 1329629baa8cSmrg name = home_name; 1330629baa8cSmrg setenv = 0; 1331629baa8cSmrg } else { 1332629baa8cSmrg Debug ("openFiles failed\n"); 1333629baa8cSmrg XauUnlockAuth (home_name); 1334629baa8cSmrg lockStatus = LOCK_ERROR; 1335629baa8cSmrg if (old != NULL) { 1336629baa8cSmrg (void) fclose (old); 1337629baa8cSmrg old = NULL; 1338629baa8cSmrg } 1339629baa8cSmrg if (new != NULL) 1340629baa8cSmrg (void) fclose (new); 1341629baa8cSmrg } 1342629baa8cSmrg } 1343629baa8cSmrg } 1344629baa8cSmrg if (lockStatus != LOCK_SUCCESS) { 1345629baa8cSmrg snprintf (backup_name, sizeof(backup_name), 1346629baa8cSmrg "%s/.XauthXXXXXX", d->userAuthDir); 1347629baa8cSmrg#ifdef HAVE_MKSTEMP 1348629baa8cSmrg fd = mkstemp (backup_name); 1349629baa8cSmrg if (fd >= 0) { 1350629baa8cSmrg old = fdopen (fd, "r"); 1351629baa8cSmrg if (old == NULL) 1352629baa8cSmrg (void) close(fd); 1353629baa8cSmrg } 1354629baa8cSmrg 1355629baa8cSmrg if (old != NULL) 1356629baa8cSmrg#else 1357629baa8cSmrg (void) mktemp (backup_name); 1358629baa8cSmrg#endif 1359629baa8cSmrg { 1360629baa8cSmrg lockStatus = XauLockAuth (backup_name, 1, 2, 10); 1361629baa8cSmrg Debug ("backup lock is %d\n", lockStatus); 1362629baa8cSmrg if (lockStatus == LOCK_SUCCESS) { 1363629baa8cSmrg if (openFiles (backup_name, new_name, &old, &new) 1364629baa8cSmrg && (old != NULL) && (new != NULL)) { 1365629baa8cSmrg name = backup_name; 1366629baa8cSmrg setenv = 1; 1367629baa8cSmrg } else { 1368629baa8cSmrg XauUnlockAuth (backup_name); 1369629baa8cSmrg lockStatus = LOCK_ERROR; 1370629baa8cSmrg if (old != NULL) { 1371629baa8cSmrg (void) fclose (old); 1372629baa8cSmrg old = NULL; 1373629baa8cSmrg } 1374629baa8cSmrg if (new != NULL) 1375629baa8cSmrg (void) fclose (new); 1376629baa8cSmrg } 1377629baa8cSmrg#ifdef HAVE_MKSTEMP 1378629baa8cSmrg } else { 1379629baa8cSmrg (void) fclose (old); 1380629baa8cSmrg#endif 1381629baa8cSmrg } 1382629baa8cSmrg } 1383629baa8cSmrg } 1384629baa8cSmrg if (lockStatus != LOCK_SUCCESS) { 1385629baa8cSmrg Debug ("can't lock auth file %s or backup %s\n", 1386629baa8cSmrg home_name, backup_name); 1387629baa8cSmrg LogError ("can't lock authorization file %s or backup %s\n", 1388629baa8cSmrg home_name, backup_name); 1389629baa8cSmrg return; 1390629baa8cSmrg } 1391629baa8cSmrg initAddrs (); 1392629baa8cSmrg doWrite = 1; 1393629baa8cSmrg Debug ("%d authorization protocols for %s\n", d->authNum, d->name); 1394629baa8cSmrg /* 1395629baa8cSmrg * Write MIT-MAGIC-COOKIE-1 authorization first, so that 1396629baa8cSmrg * R4 clients which only knew that, and used the first 1397629baa8cSmrg * matching entry will continue to function 1398629baa8cSmrg */ 1399629baa8cSmrg magicCookie = -1; 1400629baa8cSmrg for (i = 0; i < d->authNum; i++) 1401629baa8cSmrg { 1402629baa8cSmrg if (auths[i]->name_length == 18 && 1403629baa8cSmrg !strncmp (auths[i]->name, "MIT-MAGIC-COOKIE-1", 18)) 1404629baa8cSmrg { 1405629baa8cSmrg magicCookie = i; 1406629baa8cSmrg if (d->displayType.location == Local) 1407629baa8cSmrg writeLocalAuth (new, auths[i], d->name); 1408629baa8cSmrg#ifdef XDMCP 1409629baa8cSmrg else 1410629baa8cSmrg writeRemoteAuth (new, auths[i], d->peer, d->peerlen, d->name); 1411629baa8cSmrg#endif 1412629baa8cSmrg break; 1413629baa8cSmrg } 1414629baa8cSmrg } 1415629baa8cSmrg /* now write other authorizations */ 1416629baa8cSmrg for (i = 0; i < d->authNum; i++) 1417629baa8cSmrg { 1418629baa8cSmrg if (i != magicCookie) 1419629baa8cSmrg { 1420629baa8cSmrg data_len = auths[i]->data_length; 1421629baa8cSmrg /* client will just use default Kerberos cache, so don't 1422629baa8cSmrg * even write cache info into the authority file. 1423629baa8cSmrg */ 1424629baa8cSmrg if (auths[i]->name_length == 14 && 1425629baa8cSmrg !strncmp (auths[i]->name, "MIT-KERBEROS-5", 14)) 1426629baa8cSmrg auths[i]->data_length = 0; 1427629baa8cSmrg if (d->displayType.location == Local) 1428629baa8cSmrg writeLocalAuth (new, auths[i], d->name); 1429629baa8cSmrg#ifdef XDMCP 1430629baa8cSmrg else 1431629baa8cSmrg writeRemoteAuth (new, auths[i], d->peer, d->peerlen, d->name); 1432629baa8cSmrg#endif 1433629baa8cSmrg auths[i]->data_length = data_len; 1434629baa8cSmrg } 1435629baa8cSmrg } 1436629baa8cSmrg if (old) { 1437629baa8cSmrg if (fstat (fileno (old), &statb) != -1) 1438629baa8cSmrg chmod (new_name, (int) (statb.st_mode & 0777)); 1439629baa8cSmrg /*SUPPRESS 560*/ 1440629baa8cSmrg while ((entry = XauReadAuth (old))) { 1441629baa8cSmrg if (!checkEntry (entry)) 1442629baa8cSmrg { 1443629baa8cSmrg Debug ("Writing an entry\n"); 1444629baa8cSmrg writeAuth (new, entry); 1445629baa8cSmrg } 1446629baa8cSmrg XauDisposeAuth (entry); 1447629baa8cSmrg } 1448629baa8cSmrg fclose (old); 1449629baa8cSmrg } 1450629baa8cSmrg doneAddrs (); 1451629baa8cSmrg fclose (new); 1452629baa8cSmrg if (unlink (name) == -1) 1453629baa8cSmrg if (errno != ENOENT) 1454629baa8cSmrg LogError ("cannot remove old authorization file %s: %s\n", 1455629baa8cSmrg name, _SysErrorMsg (errno)); 1456629baa8cSmrg envname = name; 1457629baa8cSmrg if (link (new_name, name) == -1) { 1458629baa8cSmrg LogError ("cannot link temporary authorization file %s to old " 1459629baa8cSmrg "location %s: %s\n", new_name, name, 1460629baa8cSmrg _SysErrorMsg (errno)); 1461629baa8cSmrg setenv = 1; 1462629baa8cSmrg envname = new_name; 1463629baa8cSmrg } else { 1464629baa8cSmrg Debug ("authorization file %s successfully updated\n", name); 1465629baa8cSmrg if (unlink (new_name)) 1466629baa8cSmrg if (errno != ENOENT) 1467629baa8cSmrg LogError ("cannot remove new authorization file %s:" 1468629baa8cSmrg " %s\n", new_name, _SysErrorMsg (errno)); 1469629baa8cSmrg } 1470629baa8cSmrg if (setenv) { 1471629baa8cSmrg verify->userEnviron = setEnv (verify->userEnviron, 1472629baa8cSmrg "XAUTHORITY", envname); 1473629baa8cSmrg verify->systemEnviron = setEnv (verify->systemEnviron, 1474629baa8cSmrg "XAUTHORITY", envname); 1475629baa8cSmrg } 1476629baa8cSmrg XauUnlockAuth (name); 1477629baa8cSmrg if (envname) 1478629baa8cSmrg chown (envname, verify->uid, verify->gid); 1479629baa8cSmrg } 1480629baa8cSmrg Debug ("done SetUserAuthorization\n"); 1481629baa8cSmrg} 1482629baa8cSmrg 1483629baa8cSmrgvoid 1484629baa8cSmrgRemoveUserAuthorization (struct display *d, struct verify_info *verify) 1485629baa8cSmrg{ 1486629baa8cSmrg char *home; 1487629baa8cSmrg Xauth **auths, *entry; 1488629baa8cSmrg char name[1024], new_name[1024]; 1489629baa8cSmrg int lockStatus; 1490629baa8cSmrg FILE *old, *new; 1491629baa8cSmrg struct stat statb; 1492629baa8cSmrg int i; 1493629baa8cSmrg 1494629baa8cSmrg if (!(auths = d->authorizations)) 1495629baa8cSmrg return; 1496629baa8cSmrg home = getEnv (verify->userEnviron, "HOME"); 1497629baa8cSmrg if (!home) 1498629baa8cSmrg return; 1499629baa8cSmrg Debug ("RemoveUserAuthorization\n"); 1500629baa8cSmrg snprintf(name, sizeof(name), "%s/.Xauthority", home); 1501629baa8cSmrg Debug ("XauLockAuth %s\n", name); 1502629baa8cSmrg lockStatus = XauLockAuth (name, 1, 2, 10); 1503629baa8cSmrg Debug ("Lock is %d\n", lockStatus); 1504629baa8cSmrg if (lockStatus != LOCK_SUCCESS) 1505629baa8cSmrg return; 1506629baa8cSmrg old = NULL; 1507629baa8cSmrg if (openFiles (name, new_name, &old, &new)) 1508629baa8cSmrg { 1509629baa8cSmrg initAddrs (); 1510629baa8cSmrg doWrite = 0; 1511629baa8cSmrg for (i = 0; i < d->authNum; i++) 1512629baa8cSmrg { 1513629baa8cSmrg if (d->displayType.location == Local) 1514629baa8cSmrg writeLocalAuth (new, auths[i], d->name); 1515629baa8cSmrg#ifdef XDMCP 1516629baa8cSmrg else 1517629baa8cSmrg writeRemoteAuth (new, auths[i], d->peer, d->peerlen, d->name); 1518629baa8cSmrg#endif 1519629baa8cSmrg } 1520629baa8cSmrg doWrite = 1; 1521629baa8cSmrg if (old) { 1522629baa8cSmrg if (fstat (fileno (old), &statb) != -1) 1523629baa8cSmrg chmod (new_name, (int) (statb.st_mode & 0777)); 1524629baa8cSmrg /*SUPPRESS 560*/ 1525629baa8cSmrg while ((entry = XauReadAuth (old))) { 1526629baa8cSmrg if (!checkEntry (entry)) 1527629baa8cSmrg { 1528629baa8cSmrg Debug ("Writing an entry\n"); 1529629baa8cSmrg writeAuth (new, entry); 1530629baa8cSmrg } 1531629baa8cSmrg XauDisposeAuth (entry); 1532629baa8cSmrg } 1533629baa8cSmrg fclose (old); 1534629baa8cSmrg } 1535629baa8cSmrg doneAddrs (); 1536629baa8cSmrg fclose (new); 1537629baa8cSmrg if (unlink (name) == -1) 1538629baa8cSmrg if (errno != ENOENT) 1539629baa8cSmrg LogError ("cannot remove new authorization file %s: %s\n", 1540629baa8cSmrg name, _SysErrorMsg (errno)); 1541629baa8cSmrg if (link (new_name, name) == -1) { 1542629baa8cSmrg LogError ("cannot link temporary authorization file %s to old " 1543629baa8cSmrg "location %s: %s\n", new_name, name, 1544629baa8cSmrg _SysErrorMsg (errno)); 1545629baa8cSmrg } else { 1546629baa8cSmrg Debug ("authorization file %s successfully updated\n", name); 1547629baa8cSmrg if (unlink (new_name)) 1548629baa8cSmrg if (errno != ENOENT) 1549629baa8cSmrg LogError ("cannot remove new authorization file %s:" 1550629baa8cSmrg " %s\n", new_name, _SysErrorMsg (errno)); 1551629baa8cSmrg } 1552629baa8cSmrg } 1553629baa8cSmrg XauUnlockAuth (name); 1554629baa8cSmrg} 1555