diff options
-rw-r--r-- | ax25/ax25d.c | 2 | ||||
-rw-r--r-- | ax25/axctl.c | 2 | ||||
-rw-r--r-- | ax25/axspawn.c | 86 | ||||
-rw-r--r-- | ax25/axspawn.conf | 4 | ||||
-rw-r--r-- | ax25/axspawn.conf.5 | 6 | ||||
-rw-r--r-- | netrom/netromr.c | 6 | ||||
-rw-r--r-- | netrom/nrattach.c | 3 | ||||
-rw-r--r-- | rose/rsattach.c | 3 |
8 files changed, 94 insertions, 18 deletions
diff --git a/ax25/ax25d.c b/ax25/ax25d.c index 4d7007a..4694fb9 100644 --- a/ax25/ax25d.c +++ b/ax25/ax25d.c @@ -185,7 +185,7 @@ struct axlist { /* Have used same struct for quickness */ static struct axlist *AXL; static char *ConfigFile = CONF_AX25D_FILE; static char User[10]; /* Room for 'GB9ZZZ-15\0' */ -static char Node[10]; /* Room for 'GB9ZZZ-15\0' */ +static char Node[11]; /* Room for 'GB9ZZZ-15\0' (NETROM) and 10 bytes ROSE '6505551234\0' */ static char myAX25Name[10]; /* Room for 'GB9ZZZ-15\0' */ static char *Port; static int Logging = FALSE; diff --git a/ax25/axctl.c b/ax25/axctl.c index 45c742a..f1116a7 100644 --- a/ax25/axctl.c +++ b/ax25/axctl.c @@ -85,7 +85,7 @@ int main(int argc, char **argv) ax25_ctl.digi_count = 0; if (ioctl(s, SIOCAX25CTLCON, &ax25_ctl) != 0) { - perror("axctl: SIOAX25CTLCON"); + perror("axctl: SIOCAX25CTLCON"); return 1; } diff --git a/ax25/axspawn.c b/ax25/axspawn.c index 643ef74..4b1e410 100644 --- a/ax25/axspawn.c +++ b/ax25/axspawn.c @@ -163,6 +163,7 @@ #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/file.h> +#include <sys/wait.h> #include <config.h> @@ -437,6 +438,7 @@ char secure_home; gid_t user_gid = 400; char *user_shell = "/bin/bash"; +int user_shell_configured = 0; char *start_home = "/home/hams"; char *guest = "guest"; int start_uid = 400; @@ -1020,6 +1022,22 @@ void cleanup(char *tty) } +/* On debian wheezy, useradd (from passwd / shadow package) is buggy. + * Short before end of main, it starts the external program nscd for + * cleaning user / group cache. Their handler for waiting the forked + * process waits for child's or -1 and errno EINTR with waitpid() - else + * it loops again. + * When useradd is started by axspawn, their waitpid() returns -1 errno ECHILD, + * which leads their do-while-function go into an endless loop, eating + * 100% CPU power. + * If we mask SIGCHLD before execve(), useradd works as it should. + */ + +void signal_handler_sigchild(int dummy) +{ + exit(0); +} + /* * add a new user to /etc/passwd and do some init */ @@ -1134,9 +1152,10 @@ end_mkdirs: */ if (policy_add_prog_useradd) { - char *opt_shell = ""; + + pid_t pid = -1; struct stat statbuf; - if (stat(USERADD_CONF, &statbuf) == -1) { + if (!user_shell_configured && stat(USERADD_CONF, &statbuf) == -1) { /* some programs need a shell explicitely specified * in /etc/passwd, although this field is not required * (and useradd does not set a shell when not @@ -1146,14 +1165,56 @@ end_mkdirs: * explecitely give the shell option to useradd, when * no useradd config file is present. */ - opt_shell = " -s \"/bin/sh\""; + user_shell_configured = 1; } - sprintf(command,"/usr/sbin/useradd -p \"%s\" -c %s -d %s -u %d -g %d -m %s%s", - ((policy_add_empty_password) ? "" : "+"), - username, userdir, uid, user_gid, newuser, opt_shell); - if (system(command) != 0) + + pid = fork(); + if (pid == -1) goto out; + else if (pid == 0) { + int chargc = 0; + char *chargv[20]; + char *envp[] = { NULL }; + char s_uid[32]; + char s_gid[32]; + + sprintf(s_uid, "%d", uid); + sprintf(s_gid, "%d", user_gid); + + chargv[chargc++] = "/usr/sbin/useradd"; + chargv[chargc++] = "-p"; + chargv[chargc++] = ((policy_add_empty_password) ? "" : "+"); + chargv[chargc++] = "-c"; + chargv[chargc++] = username; + chargv[chargc++] = "-d"; + chargv[chargc++] = userdir; + chargv[chargc++] = "-u"; + chargv[chargc++] = s_uid; + chargv[chargc++] = "-g"; + chargv[chargc++] = s_gid; + chargv[chargc++] = "-m"; + chargv[chargc++] = newuser; + if (user_shell_configured) { + chargv[chargc++] = "-s"; + chargv[chargc++] = user_shell; + } + chargv[chargc] = NULL; + + /* signal SIGCHLD: see description above */ + signal(SIGCHLD, signal_handler_sigchild); + execve(chargv[0], chargv, envp); + } else { + int status; + pid_t wpid = -1; + wpid = waitpid(-1, &status, 0); + if (wpid == -1) + goto out; + if (!WIFEXITED(status)) + goto out; + } + } else { + fp = fopen(PASSWDFILE, "a+"); if (fp == NULL) goto out; @@ -1172,6 +1233,7 @@ end_mkdirs: goto out; fclose(fp); + } /* @@ -1229,8 +1291,8 @@ void read_config(void) while (!feof(fp)) { fgets(buf, sizeof(buf), fp); - p = strchr(buf, '#'); - if (p) *p='\0'; + if ((p = strchr(buf, '#')) || (p = strchr(buf, '\n'))) + *p='\0'; if (buf[0] != '\0') { @@ -1309,6 +1371,7 @@ void read_config(void) { user_shell = (char *) malloc(strlen(param)+1); strcpy(user_shell, param); + user_shell_configured = 1; } else { printf("error in config: ->%s %s<-\n", cmd, param); @@ -1541,6 +1604,11 @@ int main(int argc, char **argv) new_user(as_user); pw = getpwnam(as_user); endpwent(); + if (pw == NULL) { + syslog(LOG_NOTICE, "%s (callsign: %s) not found in /etc/passwd, even aver new_user()\n", as_user, call); + sleep(EXITDELAY); + return 1; + } } if (pw == NULL && policy_guest) diff --git a/ax25/axspawn.conf b/ax25/axspawn.conf index 5935d34..ee060a9 100644 --- a/ax25/axspawn.conf +++ b/ax25/axspawn.conf @@ -43,7 +43,9 @@ home /home/hams # secure homedirectories (g-rwx) #secure_home yes # -# user shell +# user's shell (if not configured, it's /bin/bash, or if +# create_with_useradd is set, useradd uses the shell +# configured in /etc/default/useradd). shell /bin/bash # # bind user id to callsign for outgoing connects. diff --git a/ax25/axspawn.conf.5 b/ax25/axspawn.conf.5 index cb33d9a..8b2e64b 100644 --- a/ax25/axspawn.conf.5 +++ b/ax25/axspawn.conf.5 @@ -79,7 +79,11 @@ home /home/hams .br # .br -# user's shell +# user's shell (if not configured, it's /bin/bash, or if +.br +# create_with_useradd is set, useradd uses the shell +.br +# configured in /etc/default/useradd). .br shell /bin/bash .br diff --git a/netrom/netromr.c b/netrom/netromr.c index 1f2e89d..605aa2d 100644 --- a/netrom/netromr.c +++ b/netrom/netromr.c @@ -106,14 +106,14 @@ static int add_node(int s, unsigned char *buffer, struct nr_route_struct *nr_nod return FALSE; } - if (best_quality < port_list[index].worst_qual) { + nr_node->quality = ((quality * best_quality) + 128) / 256; + + if (nr_node->quality < port_list[index].worst_qual) { if (debug && logging) syslog(LOG_DEBUG, "netromr: add_node: quality less than worst_qual"); return FALSE; } - nr_node->quality = ((quality * best_quality) + 128) / 256; - /* log this only when logging verbosely */ if (debug > 1 && logging) { syslog(LOG_DEBUG, "Node update: %s:%s", diff --git a/netrom/nrattach.c b/netrom/nrattach.c index d2209aa..804e4b8 100644 --- a/netrom/nrattach.c +++ b/netrom/nrattach.c @@ -7,6 +7,7 @@ #include <signal.h> #include <ctype.h> #include <netdb.h> +#include <limits.h> #include <config.h> @@ -104,7 +105,7 @@ int getfreedev(char *dev) return FALSE; } - for (i = 0; i < 4; i++) { + for (i = 0; i < INT_MAX; i++) { sprintf(dev, "nr%d", i); strcpy(ifr.ifr_name, dev); diff --git a/rose/rsattach.c b/rose/rsattach.c index eedf506..df042aa 100644 --- a/rose/rsattach.c +++ b/rose/rsattach.c @@ -7,6 +7,7 @@ #include <signal.h> #include <ctype.h> #include <netdb.h> +#include <limits.h> #include <config.h> @@ -88,7 +89,7 @@ int getfreedev(char *dev) return FALSE; } - for (i = 0; i < 6; i++) { + for (i = 0; i < INT_MAX; i++) { sprintf(dev, "rose%d", i); strcpy(ifr.ifr_name, dev); |