severity 328777 wishlist tags 328777 + wontfix -- This isn't really functionality that belongs in getty. lamont
On Sat, Sep 17, 2005 at 01:55:41PM +0200, Gürkan Sengün wrote: > Package: util-linux > Version: 2.12p > > I've created a little patch to allow a loginname like > [EMAIL PROTECTED]:1 > or [EMAIL PROTECTED] > that'll run ssh -p1 [EMAIL PROTECTED] or [EMAIL PROTECTED] > > this is not well tested, what are your thoughts of the usefulness (or not of > it)? > > yours, > Gürkan > <agetty.c.remote.patch> > --- agetty.c.orig 2002-07-29 09:36:42.000000000 +0200 > +++ agetty.c 2005-09-17 13:42:20.000000000 +0200 > @@ -11,6 +11,8 @@ > 1999-05-05 Thorsten Kranzkowski <[EMAIL PROTECTED]> > - enable hardware flow control before displaying /etc/issue > > + 2005-09-17 Guerkan Senguen <[EMAIL PROTECTED]> > + - enable remote logins without local account via ssh > */ > > #include <stdio.h> > @@ -30,6 +32,8 @@ > #include <getopt.h> > #include <time.h> > #include <sys/file.h> > +#include <sys/vt.h> > +#include <linux/tty.h> > #include "xstrncpy.h" > #include "nls.h" > > @@ -249,11 +253,64 @@ > #define debug(s) /* nothing */ > #endif > > +int numtokens(char *str, char delimiter) > +{ > + int i,c=1; > + for(i=0; i<strlen(str); i++) { > + if(str[i]==delimiter) c++; > + } > + return c; > +} > + > +char *gettoken(char *str, int num, char delimiter) > +{ > + char *ret; > + int c; > + int p=0; > + int last=0; > + int slen=strlen(str); > + > + for(c=0; c<=slen; c++) { > + if (c==slen-1+1) { > + /*printf("eos(%d/%d)\n",c,slen-1);*/ > + p++; > + } > + if (str[c]==delimiter) { > + c++; > + p++; > + /*printf("%d %d\n",p,c);*/ > + if (p==num) break; > + last=c; > + } > + } > + /*printf("%d %d: %d %d (%d)\n",p,num,last,c,c-last);*/ > + > + ret=malloc(c-last+1); /*-1*/ > + strncpy(ret,str+last,c-last); > + /*ret[c-last-1]='\0';*/ /* -1 */ > + if (c-1==slen-1) { > + ret[c-last]='\0'; > + } else { > + ret[c-last-1]='\0'; > + } > + > + if (p!=num) { > + /*printf("oops\n");*/ > + strcpy(ret,""); > + } > + return ret; > +} > + > int > main(argc, argv) > int argc; > char **argv; > { > + char *remoteuser = NULL; > + char *remotehost = NULL; > + char *remoteport = NULL; > + char rport[512] = ""; > + char rcommand[512] = ""; > char *logname = NULL; /* login name, given to /bin/login */ > struct chardata chardata; /* set by get_logname() */ > struct termio termio; /* terminal mode bits */ > @@ -380,6 +437,32 @@ > > (void) write(1, "\n", 1); > > + /* Allow remote logins using ssh [EMAIL PROTECTED]:anotherport] */ > + > + if (strstr(logname,"@") != NULL) { > + remoteuser=gettoken(logname,1,'@'); > + remotehost=gettoken(logname,2,'@'); > + remoteport=gettoken(logname,2,':'); > + > + if (strstr(logname,":") != NULL) { > + strcpy(rport,"-p"); > + strcat(rport,remoteport); > + remotehost=gettoken(remotehost,1,':'); > + } > + > + strcat(rcommand,remoteuser); > + strcat(rcommand,"@"); > + strcat(rcommand,remotehost); > + > + /* printf("EXECLP ssh %s\n",rcommand); > + printf("user %s\n",remoteuser); > + printf("host %s\n",remotehost); > + printf("port %s\n",remoteport); */ > + execlp("ssh", "ssh", rport, rcommand, NULL); > + error(_("ssh: can't exec %s: %m"), rcommand); > + exit(0); /* quiet GCC */ > + } > + > /* Let the login program take care of password validation. */ > > (void) execl(options.login, options.login, "--", logname, (char *) 0); > @@ -652,6 +735,91 @@ > if ((st.st_mode & S_IFMT) != S_IFCHR) > error(_("/dev/%s: not a character device"), tty); > > + /* > + * Try to avoid opening a vt that is already open, as this will > + * mean that the keyboard will be unusable. > + * > + * Unfortunately, all the kernel gives us to find out is an ioctl > + * for the next available vt. As the kernel doesn't open the vt for > + * you with the ioctl, there is still a chance of both processes > + * opening the same vt, but this check is far better than nothing at > + * all. > + * > + * The kernel API sucks, and is unusable for this situation. What > + * we really need is an ioctl that says 'does anyone _ELSE_ have > + * this tty open', and that doesn't exist. Or better yet, the > + * kernel really shouldn't allow two processes to have read access > + * on the same tty at the same time (other than with dup...) Opens > + * of the same tty device shouldn't be able to steal reads from > + * each other. > + * > + * Similar to the check added to gdm. > + * > + * For now, just turn off this check, restoring the bug that ?dm > + * (and the system) occasionally get their keyboard locked out by > + * getty showing up after they've taken a vt that inittab says > + * goes to a getty. > + * Bummer. > + * > + */ > +#if 0 > + if (strncmp(tty,"tty",3) == 0) > + { > + char *end; > + int vtno; > + > + vtno = strtol(tty+3,&end,10); > + if (end != tty+3 && *end == '\0' && vtno > 1) > + { > + int fd; > + int newvtno; > + int fds[MAX_NR_CONSOLES]; > + int vt_cnt = 0; > + int i; > + > + for ( i = 0 ; i < MAX_NR_CONSOLES ; i++ ) > + fds[i] = -1; > + > + if ((fd = open("/dev/tty0", O_WRONLY, 0) ) < 0 > + && errno != ENOENT) > + error(_("/dev/tty0: cannot open: %m")); > + > + if (fd >= 0) do > + { > + if ((ioctl(fd, VT_OPENQRY, &newvtno ) < 0)) > + error(_("failed to query next available vt")); > + > + if (newvtno == -1) > + error(_("all vts are in use")); > + > + if (newvtno > vtno) > + error(_("/dev/%s: already in use"), tty); > + > + if (newvtno < vtno) > + { > + char vtname[TTY_NAME_MAX+3]; > + > + sprintf( vtname, "tty%d", newvtno ); > + > + if ((fds[vt_cnt++] = > + open(vtname, O_RDWR|O_NONBLOCK, 0)) < 0) > + { > + error(_("/dev/%s: cannot open: %m"), tty); > + } > + } > + } while (newvtno != vtno); > + > + close(fd); > + for ( i = 0 ; i < MAX_NR_CONSOLES ; i++ ) > + { > + if (fds[i] == -1) > + break; > + close(fds[i]); > + } > + } > + } > +#endif > + > /* Open the tty as standard input. */ > > (void) close(0); > @@ -1055,13 +1223,13 @@ > } > break; > case CTL('U'): > - case '@': > - cp->kill = ascval; /* set kill character */ > +/* case '@': > + cp->kill = ascval; // set kill character > while (bp > logname) { > (void) write(1, erase[cp->parity], 3); > bp--; > } > - break; > + break; */ > case CTL('D'): > exit(0); > default: