Ejemplo n.º 1
0
char test_abort(char selectbefore, int file, int sock)
{
    char str[256];
    fd_set rfds;
    struct timeval tv;
    if (selectbefore) {
        tv.tv_sec = 0;
        tv.tv_usec = 0;
        FD_ZERO(&rfds);
        FD_SET(fileno(stdin), &rfds);
        if (!select(fileno(stdin) + 1, &rfds, NULL, NULL, &tv))
            return 0;
    }
	fgets(str, sizeof(str), stdin);
    if (strstr(str, "ABOR")) {
        control_printf(SL_SUCCESS, "426 Transfer aborted.");
    	close(file);
		close(sock);
   		control_printf(SL_SUCCESS, "226 Aborted.");
         //		bftpd_log("Client aborted file transmission.\n");
      printf("Client aborted file transmission. \n");
        alarm(control_timeout);
        return 1;
	}
    return 0;
}
Ejemplo n.º 2
0
void command_pasv(char *foo)
{
	int a1, a2, a3, a4;
   socklen_t namelen;
	struct sockaddr_in localsock;
    if (epsvall) {
        control_printf(SL_FAILURE, "500 EPSV ALL has been called.");
        return;
    }
	pasvsock = socket(AF_INET, SOCK_STREAM, 0);
	sa.sin_addr.s_addr = INADDR_ANY;
	sa.sin_family = AF_INET;

    if (!config_getoption("PASSIVE_PORTS") || !strlen(config_getoption("PASSIVE_PORTS"))) {
        /* bind to any port */
        sa.sin_port = 0;
        if (bind(pasvsock, (struct sockaddr *) &sa, sizeof(sa)) == -1) {
            control_printf(SL_FAILURE, "425-Error: Unable to bind data socket.\r\n425 %s", strerror(errno));
            return;
        }
	} else {
        int i = 0, success = 0, port;
        for (;;) {
            port = int_from_list(config_getoption("PASSIVE_PORTS"), i++);
            if (port < 0)
                break;
            sa.sin_port = htons(port);
            if (bind(pasvsock, (struct sockaddr *) &sa, sizeof(sa)) == 0) {
                success = 1;
#ifdef DEBUG
//                bftpd_log("Passive mode: Successfully bound port %d\n", port);
#endif
                break;
            }
        }
        if (!success) {
            control_printf(SL_FAILURE, "425 Error: Unable to bind data socket.");
            return;
        }
        prepare_sock(pasvsock);
    }       

	if (listen(pasvsock, 1)) {
		control_printf(SL_FAILURE, "425-Error: Unable to make socket listen.\r\n425 %s",
				 strerror(errno));
		return;
	}
	namelen = sizeof(localsock);
	getsockname(pasvsock, (struct sockaddr *) &localsock, (int *) &namelen);
	sscanf((char *) inet_ntoa(name.sin_addr), "%i.%i.%i.%i",
		   &a1, &a2, &a3, &a4);
	control_printf(SL_SUCCESS, "227 Entering Passive Mode (%i,%i,%i,%i,%i,%i)", a1, a2, a3, a4,
			 ntohs(localsock.sin_port) >> 8, ntohs(localsock.sin_port) & 0xFF);
	pasv = 1;
}
Ejemplo n.º 3
0
void command_type(char *params)
{
    if ((*params == 'I') || (*params == 'i')) {
      	control_printf(SL_SUCCESS, "200 Transfer type changed to BINARY");
        xfertype = TYPE_BINARY;
    } else {
#ifdef SUPPORT_FTPD_STORAGE
        control_printf(SL_SUCCESS, "200 Transfer type changed to ASCII");
        xfertype = TYPE_ASCII;
#else
        control_printf(SL_FAILURE, "500 Type '%c' not supported. Only support BINARY mode", *params);
#endif
    }
}
Ejemplo n.º 4
0
void command_pass(char *password)
{
//printf("In command_pass password=%s\n", password); // brcm
	if (state > STATE_USER) {
		control_printf(SL_FAILURE, "503 Already logged in.");
		return;
	}
	if (bftpd_login(password)) {
//brcm		bftpd_log("Login as user '%s' failed.\n", user);
		control_printf(SL_FAILURE, "421 Login incorrect.");
      syslog(LOG_WARNING,"104051 FTP Server Login UserName or Password Error\n");
		exit(0);
	}
}
Ejemplo n.º 5
0
int dataconn()
{
	struct sockaddr foo;
	struct sockaddr_in local;
	size_t namelen = sizeof(foo);
    // brcm int curuid = geteuid();

	memset(&foo, 0, sizeof(foo));
	memset(&local, 0, sizeof(local));

	if (pasv) {
		sock = accept(pasvsock, (struct sockaddr *) &foo, &namelen);
		if (sock == -1) {
            control_printf(SL_FAILURE, "425-Unable to accept data connection.\r\n425 %s.",
                     strerror(errno));
			return 1;
		}
        close(pasvsock);
        prepare_sock(sock);
	} else {
		sock = socket(AF_INET, SOCK_STREAM, 0);
        prepare_sock(sock);
		local.sin_addr.s_addr = name.sin_addr.s_addr;
		local.sin_family = AF_INET;
#if 0 //brcm
        if (!strcasecmp(config_getoption("DATAPORT20"), "yes")) {
            seteuid(0);
            local.sin_port = htons(20);
        }
#endif //brcm
		if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0) {
			control_printf(SL_FAILURE, "425-Unable to bind data socket.\r\n425 %s.",
					strerror(errno));
			return 1;
		}
#if 0 //brcm
        if (!strcasecmp(config_getoption("DATAPORT20"), "yes"))
            seteuid(curuid);
#endif //brcm
		sa.sin_family = AF_INET;
		if (connect(sock, (struct sockaddr *) &sa, sizeof(sa)) == -1) {
			control_printf(SL_FAILURE, "425-Unable to establish data connection.\r\n"
                    "425 %s.", strerror(errno));
			return 1;
		}
	}
	control_printf(SL_SUCCESS, "150 %s data connection established.",
	               xfertype == TYPE_BINARY ? "BINARY" : "ASCII");
	return 0;
}
Ejemplo n.º 6
0
void bftpdutmp_init()
{
    //---start--- add by w145036
    //char *filename = strdup(config_getoption("PATH_BFTPDUTMP"));
    char *filename = strdup(PATH_BFTPDUTMP);
    //---end---
        if (! filename)
            return;

	if ((!strcasecmp(filename, "none")) || (!filename[0]))
		return;
    /* First we have to create the file if it doesn't exist */

    bftpdutmp = fopen(filename, "a");
    if (bftpdutmp)
        fclose(bftpdutmp);
    /* Then we can open it for reading and writing */
    if (!(bftpdutmp = fopen(filename, "r+"))) {
        bftpd_log("Could not open log file %s.", filename);
        control_printf(SL_FAILURE, "421-Could not open file %s\r\n"
                 "421 Server disabled for security reasons.", filename);
        exit(1);
    }
    rewind(bftpdutmp);
    // clean up memory
    free(filename);
}
int admin_parsecmd(char *str)
{
	int i;
	char *p, *pp;
        int string_length;
        string_length = strlen(str) - 2;
        if (string_length < 0) string_length = 0;
	str[string_length] = '\0';	/* Remove \r\n */
	p = pp = str;			/* Remove garbage in the string */
	while (*p)
		if ((unsigned char) *p < 32)
			p++;
		else
			*pp++ = *p++;
	*pp++ = 0;
	for (i = 0; admin_commands[i].name; i++) {	/* Parse command */
		if (!strncasecmp(str, admin_commands[i].name, strlen(admin_commands[i].name))) {
			cutto(str, strlen(admin_commands[i].name));
			p = str;
			while ((*p) && ((*p == ' ') || (*p == '\t')))
				p++;
			memmove(str, p, strlen(str) - (p - str) + 1);
			admin_commands[i].function(str);
			return 0;
		}
	}
	control_printf(SL_FAILURE, "500 Unknown command: \"%s\"", str);
	return 1;
}
void command_adminlogin(char *params)
{
    char adminpass[31];
    char rootpass[31];
    char buffer[256];
    char *realadminpass = config_getoption("ADMIN_PASS");
    if (sscanf(params, "%30s %30s", adminpass, rootpass) < 2)
        loginfailed();
    if (!realadminpass[0])
        loginfailed();
    if (strcmp(crypt(adminpass, realadminpass), realadminpass))
        loginfailed();
    /* Admin password is right */
    strcpy(user, "root");
    init_userinfo();
    if (checkpass(rootpass))
        loginfailed();
    /* Root password is right as well */
    signal(SIGALRM, SIG_IGN);
    control_printf(SL_SUCCESS, "230 Administrative login successful.");
    bftpd_log("Administrative login SUCCESSFUL\n");
    while (fgets(buffer, sizeof(buffer), stdin)) {
        admin_parsecmd(buffer);
    }
    exit(0);
}
Ejemplo n.º 9
0
void displayMessage(UPLOAD_RESULT result)
{

    switch (result)
    {
        case UPLOAD_OK:
 	        control_printf(SL_SUCCESS, "Ftp image done. PLEASE TYPE 'bye' or 'quit' NOW to quit ftp and the Router will start writing the image to flash.");
            break;
        case UPLOAD_FAIL_NO_MEM:
            control_printf(SL_FAILURE, "Not enough memory error.");        
            break;
        case UPLOAD_FAIL_ILLEGAL_IMAGE:
            control_printf(SL_FAILURE, "Image updating failed. The selected file contains an illegal image.  PLEASE TYPE 'bye' or 'quit' NOW to quit ftp");
            break;
        case UPLOAD_FAIL_FLASH:
        case UPLOAD_FAIL_FTP:
            control_printf(SL_FAILURE, "ftp connection failed.");
            break;
    }
}
void command_adminkick(char *strpid)
{
    unsigned long int get_pid = strtoul(strpid, NULL, 10);
    int pid;
    
    if (get_pid <= INT_MAX)
       pid = get_pid;
    else
       pid = 0;

    if (!pid)
        control_printf(SL_FAILURE, "500 Error: Given PID is not valid.");
    else if (bftpdutmp_pidexists(pid)) {
        if (kill(pid, SIGTERM))
            control_printf(SL_FAILURE, "500 Error: %s.", strerror(errno));
        else
            control_printf(SL_FAILURE, "200 OK");
    } else
        control_printf(SL_FAILURE, "500 Error: The given PID does not belong to bftpd.");
}
Ejemplo n.º 11
0
void command_epsv(char *params)
{
    struct sockaddr_in localsock;
    int namelen;
    int af;
    if (params[0]) {
        if (!strncasecmp(params, "ALL", 3))
            epsvall = 1;
        else {
            if (sscanf(params, "%i", &af) < 1) {
                control_printf(SL_FAILURE, "500 Syntax error.");
                return;
            } else {
                if (af != 1) {
                    control_printf(SL_FAILURE, "522 Protocol unsupported, use (1)");
                    return;
                }
            }
        }
    }
    pasvsock = socket(AF_INET, SOCK_STREAM, 0);
    sa.sin_addr.s_addr = INADDR_ANY;
    sa.sin_port = 0;
    sa.sin_family = AF_INET;
    if (bind(pasvsock, (struct sockaddr *) &sa, sizeof(sa)) == -1) {
		control_printf(SL_FAILURE, "500-Error: Unable to bind data socket.\r\n425 %s",
				 strerror(errno));
		return;
	}
	if (listen(pasvsock, 1)) {
		control_printf(SL_FAILURE, "500-Error: Unable to make socket listen.\r\n425 %s",
				 strerror(errno));
		return;
	}
	namelen = sizeof(localsock);
	getsockname(pasvsock, (struct sockaddr *) &localsock, (int *) &namelen);
    control_printf(SL_SUCCESS, "229 Entering extended passive mode (|||%i|)",
             ntohs(localsock.sin_port));
    pasv = 1;
}
Ejemplo n.º 12
0
void login_init()
{
    char *foo = config_getoption("INITIAL_CHROOT");
#ifdef HAVE_UTMP_H
	wtmp_init();
#endif
    if (foo[0]) { /* Initial chroot */
        if (chroot(foo) == -1) {
            control_printf(SL_FAILURE, "421 Initial chroot to '%s' failed.\r\n%s.",
                    foo, strerror(errno));
            exit(1);
        }
    }
}
Ejemplo n.º 13
0
void command_port(char *params) {
  unsigned long a0, a1, a2, a3, p0, p1, addr;
  if (epsvall) {
      control_printf(SL_FAILURE, "500 EPSV ALL has been called.");
      return;
  }
  sscanf(params, "%lu,%lu,%lu,%lu,%lu,%lu", &a0, &a1, &a2, &a3, &p0, &p1);
  addr = htonl((a0 << 24) + (a1 << 16) + (a2 << 8) + a3);
#if 0 //brcm
  if((addr != remotename.sin_addr.s_addr) &&( strncasecmp(config_getoption("ALLOW_FXP"), "yes", 3))) {
      control_printf(SL_FAILURE, "500 The given address is not yours.");
      return;
  }
#endif //brcm
  sa.sin_addr.s_addr = addr;
  sa.sin_port = htons((p0 << 8) + p1);
  if (pasv) {
    close(sock);
    pasv = 0;
  }
  control_printf(SL_SUCCESS, "200 PORT %lu.%lu.%lu.%lu:%lu OK",
           a0, a1, a2, a3, (p0 << 8) + p1);
}
Ejemplo n.º 14
0
void config_init()
{
	FILE *configfile;
	char *str;
    struct group_of_users *grp = NULL;
    struct user *usr = NULL;
    config_global.options = NULL;
    config_global.directories = NULL;
	if (!configpath)
		return;
	configfile = fopen(configpath, "r");
	if (!configfile) {
		control_printf(SL_FAILURE, "421 Unable to open configuration file.");
		exit(1);
	}
	while ((str = config_read_line(configfile))) {
		if (strchr(str, '{')) {
            replace(str, " {", "{");
            replace(str, "{ ", "{");
            replace(str, " }", "}");
            replace(str, "} ", "}");
            if (!strcasecmp(str, "global{\n")) {
                create_options(configfile, &(config_global.options), &(config_global.directories));
            } else if (strstr(str, "user ") == str) {
                if (usr) {
                    usr = usr->next = malloc(sizeof(struct user));
                } else {
                    config_users = usr = malloc(sizeof(struct user));
                }
                usr->name = strdup(str + 5);
                *strchr(usr->name, '{') = 0;
                create_options(configfile, &(usr->options), &(usr->directories));
            } else if (strstr(str, "group ") == str) {
                if (grp) {
                    grp = grp->next = malloc(sizeof(struct group_of_users));
                } else {
                    config_groups = grp = malloc(sizeof(struct group_of_users));
                }
                cutto(str, 6);
                *strchr(str, '{') = 0;
                grp->users = NULL;
                grp->next = NULL;
                grp->temp_members = strdup(str);
                create_options(configfile, &(grp->options), &(grp->directories));
            }
		}
	}
	fclose(configfile);
}
void command_adminlog(char *params)
{
    fd_set rfds;
    struct timeval tv;
    char buffer[256];
    control_printf(SL_SUCCESS, "200 Starting logfile transmission.");
    mystatuslog = statuslogforreading;
    fseek(mystatuslog, 0, SEEK_END);
    while (mystatuslog) {
        while (fgets(buffer, sizeof(buffer), mystatuslog))
            /* Don't use control_printf here, as it would generate an infinite loop */
            fprintf(stderr, "%s", buffer);
        FD_ZERO(&rfds);
        FD_SET(0, &rfds);
        tv.tv_sec = 1;
        tv.tv_usec = 0;
        if (select(1, &rfds, NULL, NULL, &tv) > 0) {
            if (!fgets(buffer, sizeof(buffer), stdin))
                exit(0);
            admin_parsecmd(buffer);
        }
    }
    control_printf(SL_SUCCESS, "202 Logfile transmission stopped.");
}
Ejemplo n.º 16
0
void command_user(char *username)
{

//printf("In command_user username=%s\n", username); // brcm

	// brcm char *alias;
	if (state) {
		control_printf(SL_FAILURE, "503 Username already given.");
		return;
	}
	mystrncpy(user, username, sizeof(user) - 1);
    userinfo_set = 1; /* Dirty! */
#if 0 // brcm 	
    alias = (char *) config_getoption("ALIAS");
    userinfo_set = 0;
	if (alias[0] != '\0')
		mystrncpy(user, alias, sizeof(user) - 1);
#endif //brcm
    init_userinfo();
#ifdef DEBUG
//	bftpd_log("Trying to log in as %s.\n", user);
#endif
#if 0 //brcm
    expand_groups();
	if (!strcasecmp(config_getoption("ANONYMOUS_USER"), "yes"))
		bftpd_login("");
	else {
		state = STATE_USER;
		control_printf(SL_SUCCESS, "331 Password please.");
	}
#endif //brcm
    state = STATE_USER; //brcm
	control_printf(SL_SUCCESS, "331 Password please."); //brcm

//printf("Done command_user username=%s\n", username); // brcm
}
Ejemplo n.º 17
0
void log_init()
{
    char *foo = config_getoption("LOGFILE");
#ifdef HAVE_SYSLOG_H
	if (!strcasecmp(foo, "syslog")) {
        log_syslog = 1;
		openlog(global_argv[0], LOG_PID, LOG_DAEMON);
	} else
#endif
    if (foo[0])
        if (!(logfile = fopen(foo, "a"))) {
    		control_printf(SL_FAILURE, "421-Could not open log file.\r\n"
    		         "421 Server disabled for security reasons.");
    		exit(1);
    	}
    statuslog = fopen(PATH_STATUSLOG, "a");
    /* This one is for the admin code. */
    statuslogforreading = fopen(PATH_STATUSLOG, "r");
}
Ejemplo n.º 18
0
void command_eprt(char *params) {
    char delim;
    int af;
    char addr[51];
    char foo[20];
    int port;
    if (epsvall) {
        control_printf(SL_FAILURE, "500 EPSV ALL has been called.");
        return;
    }
    if (strlen(params) < 5) {
        control_printf(SL_FAILURE, "500 Syntax error.");
        return;
    }
    delim = params[0];
    sprintf(foo, "%c%%i%c%%50[^%c]%c%%i%c", delim, delim, delim, delim, delim);
    if (sscanf(params, foo, &af, addr, &port) < 3) {
        control_printf(SL_FAILURE, "500 Syntax error.");
        return;
    }
    if (af != 1) {
        control_printf(SL_FAILURE, "522 Protocol unsupported, use (1)");
        return;
    }
    sa.sin_addr.s_addr = inet_addr(addr);
    if ((sa.sin_addr.s_addr != remotename.sin_addr.s_addr) && (strncasecmp(config_getoption("ALLOW_FXP"), "yes", 3))) {
        control_printf(SL_FAILURE, "500 The given address is not yours.");
        return;
    }
    sa.sin_port = htons(port);
    if (pasv) {
        close(sock);
        pasv = 0;
    }
    control_printf(SL_FAILURE, "200 EPRT %s:%i OK", addr, port);
}
void command_adminquit(char *params)
{
    control_printf(SL_SUCCESS, "221 See you later...");
    exit(0);
}
void command_adminstoplog(char *params)
{
    mystatuslog = NULL;
    control_printf(SL_SUCCESS, "201 Stopping logfile transmission.");
}
void command_admingetconf(char *params)
{
    control_printf(SL_FAILURE, "500 Not implemented yet.");
}
Ejemplo n.º 22
0
void command_pwd(char *params)
{
	control_printf(SL_SUCCESS, "257 \"%s\" is the current working directory.",
	               bftpd_cwd_getcwd());

}
void loginfailed()
{
    control_printf(SL_FAILURE, "421 Login incorrect.");
    bftpd_log("Administrative login FAILED\n");
    exit(1);
}
Ejemplo n.º 24
0
void do_fwUpdate(void)
{
    int byteRd = 0;
    char *curPtr = NULL;
    unsigned int totalAllocatedSize = 0;
    char *buffer;
    int max;
    fd_set rfds;
    struct timeval tv;
    UBOOL8 isConfigFile;

   /* reset all of our globals before starting another download */    
    imageFormat = CMS_IMAGE_FORMAT_INVALID;
    if (imagePtr)
       free(imagePtr);
    imagePtr = NULL;
    uploadSize = 0;

	if (dataconn())
	    return;
    alarm(0);

    if ((buffer = malloc(xfer_bufsize)) == NULL)
    {
        displayMessage(UPLOAD_FAIL_NO_MEM);
        return;
    }

    max = (sock > fileno(stdin) ? sock : fileno(stdin)) + 1;
    for (;;) {
        FD_ZERO(&rfds);
        FD_SET(sock, &rfds);
        FD_SET(fileno(stdin), &rfds);
        
        tv.tv_sec = data_timeout;
        tv.tv_usec = 0;
        if (!select(max, &rfds, NULL, NULL, &tv)) {
            close(sock);
            control_printf(SL_FAILURE, "426 Kicked due to data transmission timeout.");
            if (imagePtr)
                free(imagePtr);
            free(buffer);
            displayMessage(UPLOAD_FAIL_FTP);
            return;     // exit ?
        }

		  if (!((byteRd = recv(sock, buffer, xfer_bufsize, 0))))
            break;

        if (curPtr == NULL)
        {
            // Also look in tftpd.c, which does about the same thing

            isConfigFile = cmsImg_isConfigFileLikely(buffer);
            cmsLog_debug("isConfigFile = %d", isConfigFile);
            
            if (isConfigFile)
            {
               totalAllocatedSize = cmsImg_getConfigFlashSize();
            }
            else
            {
               totalAllocatedSize = cmsImg_getImageFlashSize() + cmsImg_getBroadcomImageTagSize();
               // let smd know that we are about to start a big download
               cmsImg_sendLoadStartingMsg(msgHandle, connIfName);
            }

            if ((curPtr = (char *) malloc(totalAllocatedSize)) == NULL)
            {
               cmsLog_error("Not enough memory (%d bytes needed)", totalAllocatedSize);
               free(buffer);
               cmsImg_sendLoadDoneMsg(msgHandle);
               return;
            }
            printf("%d bytes allocated for image\n", totalAllocatedSize);
            imagePtr = curPtr;   
        }

        if (uploadSize + byteRd < totalAllocatedSize)
        {
            memcpy(curPtr, buffer, byteRd);     
            curPtr += byteRd;
            uploadSize += byteRd;
        }
        else
        {
            printf("Image could not fit into %d byte buffer.\n", totalAllocatedSize);
            free(buffer);
            free(imagePtr);
            imagePtr = NULL;
            cmsImg_sendLoadDoneMsg(msgHandle);
            return;
        }
        
	}  // end for loop to read in complete image


   free(buffer);

   
   /*
    * Now we have the entire image.  Validate it.
    */
   if ((imageFormat = cmsImg_validateImage(imagePtr, uploadSize, msgHandle)) == CMS_IMAGE_FORMAT_INVALID)
   {
      displayMessage(UPLOAD_FAIL_ILLEGAL_IMAGE);
      free(imagePtr);
      imagePtr = NULL;
      cmsImg_sendLoadDoneMsg(msgHandle);
   }
   else
   {
      printf("Image validated, size=%u format=%d, waiting for quit before flashing.\n", uploadSize, imageFormat);
      displayMessage(UPLOAD_OK);  // flash image will be done when user types bye or OK
   }

   close(sock);   // this tells the ftp client that the transfer is complete
   alarm(control_timeout);

}
Ejemplo n.º 25
0
int bftpd_login(char *password)
{
#if 0	// brcm 
    char str[256];
	char *foo;
	int maxusers;
#endif //brcm
//printf("In bftpd_login password=%s, user=%s\n", password, user); // brcm
	if (!getpwnam(user)) {
        control_printf(SL_FAILURE, "421 Login incorrect.");
		return 1;
    }
    // brcm add local/remote login check
    if ((glbAccessMode == CLI_ACCESS_LOCAL && (strcmp(user, "user") && strcmp(user, "root"))) ||
        (glbAccessMode == CLI_ACCESS_REMOTE && strcmp(user, "support")))
    {
        control_printf(SL_FAILURE, "421 Login incorrect.");
	    return 1;
    }
#if 0 //brcm
	if (strncasecmp(foo = config_getoption("DENY_LOGIN"), "no", 2)) {
		if (foo[0] != '\0') {
			if (strncasecmp(foo, "yes", 3))
				control_printf(SL_FAILURE, "421-Server disabled.\r\n421 Reason: %s", foo);
			else
				control_printf(SL_FAILURE, "421 Login incorrect.");
			bftpd_log("Login as user '%s' failed: Server disabled.\n", user);
			exit(0);
		}
	}
	maxusers = strtoul(config_getoption("USERLIMIT_GLOBAL"), NULL, 10);
	if ((maxusers) && (maxusers == bftpdutmp_usercount("*"))) {
		control_printf(SL_FAILURE, "421 There are already %i users logged in.", maxusers);
		exit(0);
	}
	maxusers = strtoul(config_getoption("USERLIMIT_SINGLEUSER"), NULL, 10);
	if ((maxusers) && (maxusers == bftpdutmp_usercount(user))) {
		control_printf(SL_FAILURE, "421 User %s is already logged in %i times.", user, maxusers);
		exit(0);
	}
#endif //brcm

    if(checkuser() || checkshell()) {
		control_printf(SL_FAILURE, "421 Login incorrect.");
		exit(0);
	}
	if (checkpass(password))
		return 1;
#if 0 //brcm
	if (strcasecmp((char *) config_getoption("RATIO"), "none")) {
		sscanf((char *) config_getoption("RATIO"), "%i/%i",
			   &ratio_send, &ratio_recv);
	}
	strcpy(str, config_getoption("ROOTDIR"));
	if (!str[0])
		strcpy(str, "%h");
	replace(str, "%u", userinfo.pw_name);
	replace(str, "%h", userinfo.pw_dir);
	if (!strcasecmp(config_getoption("RESOLVE_UIDS"), "yes")) {
		passwdfile = fopen("/etc/passwd", "r");
		groupfile = fopen("/etc/group", "r");
	}
#endif //brcm
	setgid(userinfo.pw_gid);

	initgroups(userinfo.pw_name, userinfo.pw_gid);
#if 0 //brcm
	if (strcasecmp(config_getoption("DO_CHROOT"), "no")) {
		if (chroot(str)) {
			control_printf(SL_FAILURE, "421 Unable to change root directory.\r\n%s.",
					strerror(errno));
			exit(0);
		}
		if (bftpd_setuid(userinfo.pw_uid)) {
			control_printf(SL_FAILURE, "421 Unable to change uid.");
			exit(0);
		}
		if (chdir("/")) {
			control_printf(SL_FAILURE, "421 Unable to change working directory.\r\n%s.",
					 strerror(errno));
			exit(0);
		}
	} else {
		if (bftpd_setuid(userinfo.pw_uid)) {
			control_printf(SL_FAILURE, "421 Unable to change uid.");
			exit(0);
		}
		if (chdir(str)) {
			control_printf(SL_FAILURE, "230 Couldn't change cwd to '%s': %s.", str,
					 strerror(errno));
			chdir("/");
		}
	}
    new_umask();
	print_file(230, config_getoption("MOTD_USER"));
#endif //brcm
	
    control_printf(SL_SUCCESS, "230 User logged in.");

#ifdef HAVE_UTMP_H
	bftpd_logwtmp(1);
#endif
#if 0 //brcm
    bftpdutmp_log(1);
	bftpd_log("Successfully logged in as user '%s'.\n", user);

    if (config_getoption("AUTO_CHDIR")[0])
        chdir(config_getoption("AUTO_CHDIR"));
#endif //brcm        
	state = STATE_AUTHENTICATED;
//brcm	bftpd_cwd_init();

	return 0;
}