Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Message-Id: <3.0.5.32.20030608153754.0080fdb0@incoming.verizon.net> X-Sender: vze1u1tg AT incoming DOT verizon DOT net Date: Sun, 08 Jun 2003 15:37:54 -0400 To: cygwin AT cygwin DOT com, Takashi Yano From: "Pierre A. Humblet" Subject: Re: Problems on accessing Windows network resources. In-Reply-To: References: <001401c32dd7$dc721b30$2000a8c0 AT kappy> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=====================_1055115474==_" --=====================_1055115474==_ Content-Type: text/plain; charset="us-ascii" At 03:09 PM 6/8/2003 -0400, Igor Pechtchanski wrote: >Takashi, > >If you log in without a password: according to the second paragraph of >, you >cannot access network shares that require authentication from a >passwordless login session. There is no way to resolve this. However, >you should be able to authenticate using the "net use" command with a >"/user" flag. > >The only change between login-1.7-1 and login-1.8-1 was that it switches >the effective UID (user context) back to the privileged (system) account >to access utmp (and then restores to the user's UID). It may be that this >happens too early, or that switching the UID back and forth affects the >process's ability to access network shares. A small testcase (the exact >instructions on how to reproduce this) would be helpful. Corinna or >Pierre might give more insight here. Coincidentally I was just looking at that. A side effect of switching to the system account is that the user access token obtained with a password is lost. A new password-less user token is then generated, but it doesn't allow as much access. I expect this problem to be fixed within a few days. Actually I am attaching what should be a fix, but it's only tested on WinME. Feedback welcome. Compile as follows and mv the .exe to /bin gcc login.c -o login -l crypt Pierre --=====================_1055115474==_ Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="login.c" /* * Copyright (c) 1980, 1987, 1988 The Regents of the University of= California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef lint char copyright[] =3D "@(#) Copyright (c) 1980, 1987, 1988 The Regents of the University of= California.\n\ All rights reserved.\n"; #endif /* not lint */ #ifndef lint static char sccsid[] =3D "@(#)login.c 5.32.1.1 (Berkeley) 1/28/89, 1.7-1= (Cygwin) 11/14/2002"; #endif /* not lint */ /* * login [ name ] * login -h hostname (for telnetd, etc.) * login -f name (for pre-authenticated login: datakit, xterm, etc.) */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define TTYGRPNAME "tty" /* name of group to own ttys= */ #define= MOTDFILE= "/etc/motd" #define= MAILDIR= = "/usr/spool/mail" #define NOLOGIN "/etc/nologin" #define HUSHLOGIN ".hushlogin" #ifdef= __CYGWIN__ #define= LASTLOG= = "/var/log/lastlog" #else #define LASTLOG "/usr/adm/lastlog" #endif #define BSHELL "/bin/sh" #ifdef __CYGWIN__ #include #include #define is_winnt (GetVersion() < 0x80000000) #endif #ifdef __CYGWIN__ #define ROOT_UID 18 // system #else #define ROOT_UID 0 #endif /* * This bounds the time given to login. Not a define so it can * be patched on machines where it's too small. */ int timeout =3D 300; struct passwd *pwd; int failures; char term[64], *hostname, *username, *tty; main(argc, argv) int argc; char **argv; { extern int errno, optind; extern char *optarg, **environ; struct group *gr; register int ch; register char *p; int ask, fflag, hflag, pflag, cnt; int quietlog, passwd_req, ioctlval; #ifdef __CYGWIN__ int priv_uid; int priv_gid; #endif void timedout(); char *domain, *salt, *envinit[1], *ttyn, *pp; char tbuf[MAXPATHLEN + 2]; char *ttyname(), *crypt(), *getpass(); time_t time(); off_t lseek(); (void)signal(SIGALRM,= timedout); (void)alarm((u_int)timeout); (void)signal(SIGQUIT, SIG_IGN); (void)signal(SIGINT, SIG_IGN); /* * -p is used by getty to tell login not to destroy the environment * -f is used to skip a second login authentication * -h is used by other servers to pass the name of the remote * host to login so that it may be placed in utmp and wtmp */ (void)gethostname(tbuf, sizeof(tbuf)); domain =3D index(tbuf, '.'); fflag =3D hflag =3D pflag =3D 0; passwd_req =3D 1; while ((ch =3D getopt(argc, argv, "fh:p")) !=3D EOF) switch (ch) { case 'f': fflag =3D 1; break; case 'h': #ifndef __CYGWIN__ if (getuid()) { fprintf(stderr, "login: -h for super-user= only.\n"); exit(1); } #endif hflag =3D 1; if (domain && (p =3D index(optarg, '.')) && strcasecmp(p, domain) =3D=3D 0) *p =3D 0; hostname =3D optarg; break; case 'p': pflag =3D 1; break; case '?': default: fprintf(stderr, "usage: login [-fp] [username]\n"); exit(1); } argc -=3D optind; argv +=3D optind; if (*argv) { username =3D *argv; ask =3D 0; } else ask =3D 1; for (cnt =3D getdtablesize(); cnt > 2; cnt--) close(cnt); ttyn =3D ttyname(0); if (ttyn =3D=3D NULL || *ttyn =3D=3D '\0') ttyn =3D "/dev/tty??"; if (tty =3D rindex(ttyn, '/')) ++tty; else tty =3D ttyn; openlog("login", LOG_ODELAY, LOG_AUTH); for (cnt =3D 0;; ask =3D 1) { #ifndef __CYGWIN__ ioctlval =3D 0; (void)ioctl(0, TIOCSETD, &ioctlval); #endif if (ask) { fflag =3D 0; getloginname(); } /* * Note if trying multiple user names; * log failures for previous user name, * but don't bother logging one failure * for nonexistent name (mistyped username). */ if (failures && strcmp(tbuf, username)) { if (failures > (pwd ? 0 : 1)) badlogin(tbuf); failures =3D 0; } (void)strcpy(tbuf, username); if (pwd =3D getpwnam(username)) salt =3D pwd->pw_passwd; else salt =3D "xx"; /* if user not super-user, check for disabled logins */ if (pwd =3D=3D NULL || pwd->pw_uid) checknologin(); /* * Disallow automatic login to root; if not invoked by * root, disallow if the uid's differ. */ if (fflag && pwd) { int uid =3D getuid(); passwd_req =3D pwd->pw_uid =3D=3D ROOT_UID || (uid !=3D ROOT_UID && uid !=3D pwd->pw_uid); } /* * If no pre-authentication and a password exists * for this user, prompt for one and verify it. */ if (!passwd_req || (pwd && !*pwd->pw_passwd)) break; pp =3D getpass("Password:"); #ifdef __CYGWIN__ if (is_winnt) { HANDLE hToken =3D cygwin_logon_user (pwd, pp); if (hToken !=3D INVALID_HANDLE_VALUE) { cygwin_set_impersonation_token (hToken); break; } } else #endif { p =3D crypt(pp, salt); if (pwd && !strcmp(p, pwd->pw_passwd)) break; } (void) bzero(pp, strlen(pp)); printf("Login incorrect\n"); failures++; /* we allow 10 tries, but after 3 we start backing off */ if (++cnt > 3) { if (cnt >=3D 10) { badlogin(username); #ifndef __CYGWIN__ (void)ioctl(0, TIOCHPCL, (struct sgttyb= *)NULL); #endif sleepexit(1); } sleep((u_int)((cnt - 3) * 5)); } } /* committed to login -- turn off timeout */ (void)alarm((u_int)0); /* * If valid so far and root is logging in, see if root logins on * this terminal are permitted. */ #ifdef __CYGWIN__ priv_gid =3D getegid(); setegid(pwd->pw_gid); /* Unfortunately we have to make sure that the user is already the right one to chmod to its home dir on Windows. */ priv_uid =3D geteuid(); if (seteuid(pwd->pw_uid)) { printf("Switching to user %s failed!\n",= username); sleep(1); exit(0); } #endif if (chdir(pwd->pw_dir) < 0) { printf("No directory %s!\n", pwd->pw_dir); if (chdir("/")) exit(0); pwd->pw_dir =3D "/"; printf("Logging in with home =3D \"/\".\n"); } /* nothing else left to fail -- really log in */ #ifdef __CYGWIN__ /* But we have to revert to the privileged user to access utmp. */ setegid (priv_gid); seteuid (priv_uid); #endif { struct utmp utmp; bzero((char *)&utmp,= sizeof(utmp)); (void)time(&utmp.ut_time); strncpy(utmp.ut_name, username, sizeof(utmp.ut_name)); if (hostname) strncpy(utmp.ut_host, hostname,= sizeof(utmp.ut_host)); strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line)); #ifdef __CYGWIN__ /* Cygwin has the Linux fields in utmp as well. */ { int len =3D strlen(tty) - sizeof(utmp.ut_id); if (len > 0) tty +=3D len; strncpy(utmp.ut_id, tty, sizeof(utmp.ut_id)); if (len > 0) tty -=3D len; utmp.ut_pid =3D getpid(); } #endif utmp.ut_type =3D USER_PROCESS; login(&utmp); } setgid(pwd->pw_gid); setuid(pwd->pw_uid); quietlog =3D access(HUSHLOGIN, F_OK) =3D=3D 0; dolastlog(quietlog); #if 0 if (!hflag) { /* XXX */ static struct winsize win =3D { 0, 0/*, 0, 0*/ }; (void)ioctl(0, TIOCSWINSZ, &win); } #endif #ifndef __CYGWIN__ initgroups(username, pwd->pw_gid); #endif if (*pwd->pw_shell =3D=3D '\0') pwd->pw_shell =3D BSHELL; /* destroy environment unless user has requested preservation */ #ifndef __CYGWIN__ if (!pflag) environ =3D envinit; #endif (void)setenv("HOME", pwd->pw_dir, 1); (void)setenv("SHELL", pwd->pw_shell, 1); #ifndef __CYGWIN__ (void)setenv("TERM", term, 0); #endif (void)setenv("USER", pwd->pw_name, 1); (void)setenv("PATH", "/usr/ucb:/bin:/usr/bin:", 0); if (tty[sizeof("tty")-1] =3D=3D 'd') syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name); if (pwd->pw_uid =3D=3D 0) if (hostname) syslog(LOG_NOTICE, "ROOT LOGIN ON %s FROM %s", tty, hostname); else syslog(LOG_NOTICE, "ROOT LOGIN ON %s", tty); if (!quietlog) { struct stat st; motd(); (void)sprintf(tbuf, "%s/%s", MAILDIR, pwd->pw_name); if (stat(tbuf, &st) =3D=3D 0 && st.st_size !=3D 0) printf("You have %smail.\n", (st.st_mtime > st.st_atime) ? "new " := ""); } (void)signal(SIGALRM, SIG_DFL); (void)signal(SIGQUIT, SIG_DFL); (void)signal(SIGINT, SIG_DFL); (void)signal(SIGTSTP, SIG_IGN); tbuf[0] =3D '-'; strcpy(tbuf + 1, (p =3D rindex(pwd->pw_shell, '/')) ? p + 1 : pwd->pw_shell); execlp(pwd->pw_shell, tbuf, 0); fprintf(stderr, "login: no shell:= "); perror(pwd->pw_shell); exit(0); } getloginname() { register int ch; register char *p; static char nbuf[UT_NAMESIZE + 1]; for (;;) { printf("login: "); for (p =3D nbuf; (ch =3D getchar()) !=3D '\n'; ) { if (ch =3D=3D EOF) { badlogin(username); exit(0); } if (p < nbuf + UT_NAMESIZE) *p++ =3D ch; } if (p > nbuf) if (nbuf[0] =3D=3D '-') fprintf(stderr, "login names may not start with '-'.\n"); else { *p =3D '\0'; username =3D nbuf; break; } } } timedout() { fprintf(stderr, "Login timed out after %d seconds\n",= timeout); exit(0); } jmp_buf motdinterrupt; motd() { register int fd, nchars; void (*oldint)(), sigint(); char tbuf[8192]; if ((fd =3D open(MOTDFILE, O_RDONLY, 0)) < 0) return; oldint =3D signal(SIGINT, sigint); if (setjmp(motdinterrupt) =3D=3D 0) while ((nchars =3D read(fd, tbuf, sizeof(tbuf))) >= 0) (void)write(fileno(stdout), tbuf, nchars); (void)signal(SIGINT,= oldint); (void)close(fd); } sigint() { longjmp(motdinterrupt, 1); } checknologin() { register int fd, nchars; char tbuf[8192]; if ((fd =3D open(NOLOGIN, O_RDONLY, 0)) >=3D 0) { while ((nchars =3D read(fd, tbuf, sizeof(tbuf))) >= 0) (void)write(fileno(stdout), tbuf,= nchars); sleepexit(0); } } dolastlog(quiet) int quiet; { struct lastlog ll; int fd; if ((fd =3D open(LASTLOG, O_RDWR, 0)) >=3D 0) { (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET); if (!quiet) { if (read(fd, (char *)&ll, sizeof(ll)) =3D=3D sizeof(ll) && ll.ll_time !=3D 0) { printf("Last login: %.*s ", 24-5, (char *)ctime(&ll.ll_time)); if (*ll.ll_host !=3D '\0') printf("from %.*s\n", sizeof(ll.ll_host), ll.ll_host); else printf("on %.*s\n", sizeof(ll.ll_line), ll.ll_line); } (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll),= L_SET); } bzero((char *)&ll,= sizeof(ll)); (void)time(&ll.ll_time); strncpy(ll.ll_line, tty, sizeof(ll.ll_line)); if (hostname) strncpy(ll.ll_host, hostname, sizeof(ll.ll_host)); (void)write(fd, (char *)&ll,= sizeof(ll)); (void)close(fd); } } badlogin(name) char *name; { if (failures =3D=3D 0) return; if (hostname) syslog(LOG_NOTICE, "%d LOGIN FAILURE%s FROM %s, %s", failures, failures > 1 ? "S" : "", hostname,= name); else syslog(LOG_NOTICE, "%d LOGIN FAILURE%s ON %s, %s", failures, failures > 1 ? "S" : "", tty, name); } getstr(buf, cnt, err) char *buf, *err; int cnt; { char ch; do { if (read(0, &ch, sizeof(ch)) !=3D sizeof(ch)) exit(1); if (--cnt < 0) { fprintf(stderr, "%s too long\r\n", err); sleepexit(1); } *buf++ =3D ch; } while (ch); } sleepexit(eval) int eval; { sleep((u_int)5); exit(eval); } --=====================_1055115474==_ Content-Type: text/plain; charset=us-ascii -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ --=====================_1055115474==_--