Example #1
0
static void manage_squid_basic_request(enum stdio_helper_mode stdio_helper_mode, 
				       char *buf, int length) 
{
	char *user, *pass;	
	user=buf;
	
	pass=memchr(buf,' ',length);
	if (!pass) {
		DEBUG(2, ("Password not found. Denying access\n"));
		x_fprintf(x_stdout, "ERR\n");
		return;
	}
	*pass='******';
	pass++;
	
	if (stdio_helper_mode == SQUID_2_5_BASIC) {
		rfc1738_unescape(user);
		rfc1738_unescape(pass);
	}
	
	if (check_plaintext_auth(user, pass, False)) {
		x_fprintf(x_stdout, "OK\n");
	} else {
		x_fprintf(x_stdout, "ERR\n");
	}
}
Example #2
0
static void manage_squid_basic_request(enum stdio_helper_mode stdio_helper_mode, 
				       struct loadparm_context *lp_ctx,
				       char *buf, int length, void **private1,
				       unsigned int mux_id, void **private2) 
{
	char *user, *pass;	
	user=buf;
	
	pass = memchr(buf, ' ', length);
	if (!pass) {
		DEBUG(2, ("Password not found. Denying access\n"));
		mux_printf(mux_id, "ERR\n");
		return;
	}
	*pass='******';
	pass++;
	
	if (stdio_helper_mode == SQUID_2_5_BASIC) {
		rfc1738_unescape(user);
		rfc1738_unescape(pass);
	}
	
	if (check_plaintext_auth(user, pass, false)) {
		mux_printf(mux_id, "OK\n");
	} else {
		mux_printf(mux_id, "ERR\n");
	}
}
int
main(int argc, char **argv)
{
    struct stat sb;
    time_t change_time = -1;
    char buf[256];
    char *user, *passwd, *p;
    user_data *u;
    setbuf(stdout, NULL);
    if (argc != 2) {
	fprintf(stderr, "Usage: ncsa_auth <passwordfile>\n");
	exit(1);
    }
    if (stat(argv[1], &sb) != 0) {
	fprintf(stderr, "cannot stat %s\n", argv[1]);
	exit(1);
    }
    while (fgets(buf, 256, stdin) != NULL) {
	if ((p = strchr(buf, '\n')) != NULL)
	    *p = '\0';		/* strip \n */
	if (stat(argv[1], &sb) == 0) {
	    if (sb.st_mtime != change_time) {
		read_passwd_file(argv[1]);
		change_time = sb.st_mtime;
	    }
	}
	if ((user = strtok(buf, " ")) == NULL) {
	    printf("ERR\n");
	    continue;
	}
	if ((passwd = strtok(NULL, "")) == NULL) {
	    printf("ERR\n");
	    continue;
	}
	rfc1738_unescape(user);
	rfc1738_unescape(passwd);
	u = (user_data *) hash_lookup(hash, user);
	if (u == NULL) {
	    printf("ERR No such user\n");
#if HAVE_CRYPT
	} else if (strcmp(u->passwd, (char *) crypt(passwd, u->passwd)) == 0) {
	    printf("OK\n");
#endif
	} else if (strcmp(u->passwd, (char *) crypt_md5(passwd, u->passwd)) == 0) {
	    printf("OK\n");
	} else if (strcmp(u->passwd, (char *) md5sum(passwd)) == 0) {	/* md5 without salt and magic strings - Added by Ramon de Carvalho and Rodrigo Rubira Branco */
	    printf("OK\n");
	} else {
	    printf("ERR Wrong password\n");
	}
    }
    if (hash != NULL) {
	hashFreeItems(hash, my_free);
	hashFreeMemory(hash);
    }
    exit(0);
}
Example #4
0
static cachemgr_request *
read_request(void)
{
    char *buf;
    cachemgr_request *req;
    char *s;
    char *t;
    char *q;
    if ((buf = read_post_request()) != NULL)
	(void) 0;
    else if ((buf = read_get_request()) != NULL)
	(void) 0;
    else
	return NULL;
#ifdef _SQUID_MSWIN_
    if (strlen(buf) == 0 || strlen(buf) == 4000)
#else
    if (strlen(buf) == 0)
#endif
	return NULL;
    req = xcalloc(1, sizeof(cachemgr_request));
    for (s = strtok(buf, "&"); s != NULL; s = strtok(NULL, "&")) {
	t = xstrdup(s);
	if ((q = strchr(t, '=')) == NULL)
	    continue;
	*q++ = '\0';
	rfc1738_unescape(t);
	rfc1738_unescape(q);
	if (0 == strcasecmp(t, "server") && strlen(q))
	    req->server = xstrdup(q);
	else if (0 == strcasecmp(t, "host") && strlen(q))
	    req->hostname = xstrdup(q);
	else if (0 == strcasecmp(t, "port") && strlen(q))
	    req->port = atoi(q);
	else if (0 == strcasecmp(t, "user_name") && strlen(q))
	    req->user_name = xstrdup(q);
	else if (0 == strcasecmp(t, "passwd") && strlen(q))
	    req->passwd = xstrdup(q);
	else if (0 == strcasecmp(t, "auth") && strlen(q))
	    req->pub_auth = xstrdup(q), decode_pub_auth(req);
	else if (0 == strcasecmp(t, "operation"))
	    req->action = xstrdup(q);
    }
    if (req->server && !req->hostname) {
	char *p;
	req->hostname = strtok(req->server, ":");
	if ((p = strtok(NULL, ":")))
	    req->port = atoi(p);
    }
    make_pub_auth(req);
    debug(1) fprintf(stderr, "cmgr: got req: host: '%s' port: %d uname: '%s' passwd: '%s' auth: '%s' oper: '%s'\n",
	safe_str(req->hostname), req->port, safe_str(req->user_name), safe_str(req->passwd), safe_str(req->pub_auth), safe_str(req->action));
    return req;
}
Example #5
0
int
main(int argc, char **argv)
{
    struct stat sb;
    time_t change_time = 0;
    char buf[256];
    char *user, *passwd, *p;
    user_data *u;
    setbuf(stdout, NULL);
    if (argc != 2) {
	fprintf(stderr, "Usage: ncsa_auth <passwordfile>\n");
	exit(1);
    }
    if (stat(argv[1], &sb) != 0) {
	fprintf(stderr, "cannot stat %s\n", argv[1]);
	exit(1);
    }
    while (fgets(buf, 256, stdin) != NULL) {
	if ((p = strchr(buf, '\n')) != NULL)
	    *p = '\0';		/* strip \n */
	if (stat(argv[1], &sb) == 0) {
	    if (sb.st_mtime != change_time) {
		read_passwd_file(argv[1]);
		change_time = sb.st_mtime;
	    }
	}
	if ((user = strtok(buf, " ")) == NULL) {
	    printf("ERR\n");
	    continue;
	}
	if ((passwd = strtok(NULL, "")) == NULL) {
	    printf("ERR\n");
	    continue;
	}
	rfc1738_unescape(user);
	rfc1738_unescape(passwd);
	u = hash_lookup(hash, user);
	if (u == NULL) {
	    printf("ERR No such user\n");
	} else if (strcmp(u->passwd, (char *) crypt(passwd, u->passwd))) {
	    printf("ERR Wrong password\n");
	} else {
	    printf("OK\n");
	}
    }
    exit(0);
}
Example #6
0
static char *uri_unescape_alloc(const char *uritok)
{
	char *ret;

	ret = (char *)SMB_STRDUP(uritok);
	if (!ret) return NULL;

	rfc1738_unescape(ret);
	return ret;
}
int
main(int argc, char **argv)
{
    int auth = 0;
    char buf[256];
    char *user, *passwd, *p;

    setbuf(stdout, NULL);
    while (fgets(buf, 256, stdin) != NULL) {

	if ((p = strchr(buf, '\n')) != NULL)
	    *p = '\0';		/* strip \n */

	if ((user = strtok(buf, " ")) == NULL) {
	    printf(ERR);
	    continue;
	}
	if ((passwd = strtok(NULL, "")) == NULL) {
	    printf(ERR);
	    continue;
	}
	rfc1738_unescape(user);
	rfc1738_unescape(passwd);
#if HAVE_SHADOW_H
	auth = shadow_auth(user, passwd);
#else
	auth = passwd_auth(user, passwd);
#endif
	if (auth == 0) {
	    printf("ERR No such user\n");
	} else {
	    if (auth == 2) {
		printf("ERR Wrong password\n");
	    } else {
		printf(OK);
	    }
	}
    }
    exit(0);
}
Example #8
0
int
main(int argc, char *argv[])
{
    char *p;
    char buf[BUFSIZE];
    char *username;
    char *group;
    int err = 0;
    const char *groups[512];
    int n;

    if (argc > 0) {		/* should always be true */
        myname = strrchr(argv[0], '/');
        if (myname == NULL)
            myname = argv[0];
    } else {
        myname = "(unknown)";
    }
    mypid = getpid();

    setbuf(stdout, NULL);
    setbuf(stderr, NULL);

    /* Check Command Line */
    process_options(argc, argv);

    if (use_global) {
        if ((machinedomain = GetDomainName()) == NULL) {
            fprintf(stderr, "%s Can't read machine domain\n", myname);
            exit(1);
        }
        strlwr(machinedomain);
        if (!DefaultDomain)
            DefaultDomain = xstrdup(machinedomain);
    }
    debug("External ACL win32 group helper build " __DATE__ ", " __TIME__
          " starting up...\n");
    if (use_global)
        debug("Domain Global group mode enabled using '%s' as default domain.\n", DefaultDomain);
    if (use_case_insensitive_compare)
        debug("Warning: running in case insensitive mode !!!\n");

    /* Main Loop */
    while (fgets(buf, sizeof(buf), stdin)) {
        if (NULL == strchr(buf, '\n')) {
            /* too large message received.. skip and deny */
            fprintf(stderr, "%s: ERROR: Too large: %s\n", argv[0], buf);
            while (fgets(buf, sizeof(buf), stdin)) {
                fprintf(stderr, "%s: ERROR: Too large..: %s\n", argv[0], buf);
                if (strchr(buf, '\n') != NULL)
                    break;
            }
            goto error;
        }
        if ((p = strchr(buf, '\n')) != NULL)
            *p = '\0';		/* strip \n */
        if ((p = strchr(buf, '\r')) != NULL)
            *p = '\0';		/* strip \r */

        debug("Got '%s' from Squid (length: %d).\n", buf, strlen(buf));

        if (buf[0] == '\0') {
            fprintf(stderr, "Invalid Request\n");
            goto error;
        }
        username = strtok(buf, " ");
        for (n = 0; (group = strtok(NULL, " ")) != NULL; n++) {
            rfc1738_unescape(group);
            groups[n] = group;
        }
        groups[n] = NULL;

        if (NULL == username) {
            fprintf(stderr, "Invalid Request\n");
            goto error;
        }
        rfc1738_unescape(username);

        if ((use_global ? Valid_Global_Groups(username, groups) : Valid_Local_Groups(username, groups))) {
            printf("OK\n");
        } else {
error:
            printf("ERR\n");
        }
        err = 0;
    }
    return 0;
}
Example #9
0
int
main(int argc, char **argv)
{
    char buf[8192];
    char *user, *group, *extension_dn = NULL;
    char *ldapServer = NULL;
    LDAP *ld = NULL;
    int tryagain = 0, rc;
    int port = LDAP_PORT;
    int use_extension_dn = 0;
    int strip_nt_domain = 0;
    int strip_kerberos_realm = 0;

    setbuf(stdout, NULL);

    while (argc > 1 && argv[1][0] == '-') {
	char *value = "";
	char option = argv[1][1];
	switch (option) {
	case 'P':
	case 'R':
	case 'z':
	case 'Z':
	case 'd':
	case 'g':
	case 'S':
	case 'K':
	    break;
	default:
	    if (strlen(argv[1]) > 2) {
		value = argv[1] + 2;
	    } else if (argc > 2) {
		value = argv[2];
		argv++;
		argc--;
	    } else
		value = "";
	    break;
	}
	argv++;
	argc--;
	switch (option) {
	case 'H':
#if !HAS_URI_SUPPORT
	    fprintf(stderr, "ERROR: Your LDAP library does not have URI support\n");
	    exit(1);
#endif
	    /* Fall thru to -h */
	case 'h':
	    if (ldapServer) {
		int len = strlen(ldapServer) + 1 + strlen(value) + 1;
		char *newhost = malloc(len);
		snprintf(newhost, len, "%s %s", ldapServer, value);
		free(ldapServer);
		ldapServer = newhost;
	    } else {
		ldapServer = strdup(value);
	    }
	    break;
	case 'b':
	    basedn = value;
	    break;
	case 'f':
	    searchfilter = value;
	    break;
	case 'B':
	    userbasedn = value;
	    break;
	case 'F':
	    usersearchfilter = value;
	    break;
	case 'u':
	    userdnattr = value;
	    break;
	case 's':
	    if (strcmp(value, "base") == 0)
		searchscope = LDAP_SCOPE_BASE;
	    else if (strcmp(value, "one") == 0)
		searchscope = LDAP_SCOPE_ONELEVEL;
	    else if (strcmp(value, "sub") == 0)
		searchscope = LDAP_SCOPE_SUBTREE;
	    else {
		fprintf(stderr, PROGRAM_NAME " ERROR: Unknown search scope '%s'\n", value);
		exit(1);
	    }
	    break;
	case 'E':
#if defined(NETSCAPE_SSL)
	    sslpath = value;
	    if (port == LDAP_PORT)
		port = LDAPS_PORT;
#else
	    fprintf(stderr, PROGRAM_NAME " ERROR: -E unsupported with this LDAP library\n");
	    exit(1);
#endif
	    break;
	case 'c':
	    connect_timeout = atoi(value);
	    break;
	case 't':
	    timelimit = atoi(value);
	    break;
	case 'a':
	    if (strcmp(value, "never") == 0)
		aliasderef = LDAP_DEREF_NEVER;
	    else if (strcmp(value, "always") == 0)
		aliasderef = LDAP_DEREF_ALWAYS;
	    else if (strcmp(value, "search") == 0)
		aliasderef = LDAP_DEREF_SEARCHING;
	    else if (strcmp(value, "find") == 0)
		aliasderef = LDAP_DEREF_FINDING;
	    else {
		fprintf(stderr, PROGRAM_NAME " ERROR: Unknown alias dereference method '%s'\n", value);
		exit(1);
	    }
	    break;
	case 'D':
	    binddn = value;
	    break;
	case 'w':
	    bindpasswd = value;
	    break;
	case 'W':
	    readSecret(value);
	    break;
	case 'P':
	    persistent = !persistent;
	    break;
	case 'p':
	    port = atoi(value);
	    break;
	case 'R':
	    noreferrals = !noreferrals;
	    break;
#ifdef LDAP_VERSION3
	case 'v':
	    switch (atoi(value)) {
	    case 2:
		version = LDAP_VERSION2;
		break;
	    case 3:
		version = LDAP_VERSION3;
		break;
	    default:
		fprintf(stderr, "Protocol version should be 2 or 3\n");
		exit(1);
	    }
	    break;
	case 'Z':
	    if (version == LDAP_VERSION2) {
		fprintf(stderr, "TLS (-Z) is incompatible with version %d\n",
		    version);
		exit(1);
	    }
	    version = LDAP_VERSION3;
	    use_tls = 1;
	    break;
#endif
	case 'd':
	    debug = 1;
	    break;
	case 'g':
	    use_extension_dn = 1;
	    break;
	case 'S':
	    strip_nt_domain = 1;
	    break;
	case 'K':
	    strip_kerberos_realm = 1;
	    break;
	default:
	    fprintf(stderr, PROGRAM_NAME " ERROR: Unknown command line option '%c'\n", option);
	    exit(1);
	}
    }

    while (argc > 1) {
	char *value = argv[1];
	if (ldapServer) {
	    int len = strlen(ldapServer) + 1 + strlen(value) + 1;
	    char *newhost = malloc(len);
	    snprintf(newhost, len, "%s %s", ldapServer, value);
	    free(ldapServer);
	    ldapServer = newhost;
	} else {
	    ldapServer = strdup(value);
	}
	argc--;
	argv++;
    }

    if (!ldapServer)
	ldapServer = "localhost";

    if (!basedn || !searchfilter) {
	fprintf(stderr, "\n" PROGRAM_NAME " version " PROGRAM_VERSION "\n\n");
	fprintf(stderr, "Usage: " PROGRAM_NAME " -b basedn -f filter [options] ldap_server_name\n\n");
	fprintf(stderr, "\t-b basedn (REQUIRED)\tbase dn under where to search for groups\n");
	fprintf(stderr, "\t-f filter (REQUIRED)\tgroup search filter pattern. %%u = user,\n\t\t\t\t%%g = group\n");
	fprintf(stderr, "\t-B basedn (REQUIRED)\tbase dn under where to search for users\n");
	fprintf(stderr, "\t-F filter (REQUIRED)\tuser search filter pattern. %%s = login\n");
	fprintf(stderr, "\t-s base|one|sub\t\tsearch scope\n");
	fprintf(stderr, "\t-D binddn\t\tDN to bind as to perform searches\n");
	fprintf(stderr, "\t-w bindpasswd\t\tpassword for binddn\n");
	fprintf(stderr, "\t-W secretfile\t\tread password for binddn from file secretfile\n");
#if HAS_URI_SUPPORT
	fprintf(stderr, "\t-H URI\t\t\tLDAPURI (defaults to ldap://localhost)\n");
#endif
	fprintf(stderr, "\t-h server\t\tLDAP server (defaults to localhost)\n");
	fprintf(stderr, "\t-p port\t\t\tLDAP server port (defaults to %d)\n", LDAP_PORT);
	fprintf(stderr, "\t-P\t\t\tpersistent LDAP connection\n");
#if defined(NETSCAPE_SSL)
	fprintf(stderr, "\t-E sslcertpath\t\tenable LDAP over SSL\n");
#endif
	fprintf(stderr, "\t-c timeout\t\tconnect timeout\n");
	fprintf(stderr, "\t-t timelimit\t\tsearch time limit\n");
	fprintf(stderr, "\t-R\t\t\tdo not follow referrals\n");
	fprintf(stderr, "\t-a never|always|search|find\n\t\t\t\twhen to dereference aliases\n");
#ifdef LDAP_VERSION3
	fprintf(stderr, "\t-v 2|3\t\t\tLDAP version\n");
	fprintf(stderr, "\t-Z\t\t\tTLS encrypt the LDAP connection, requires\n\t\t\t\tLDAP version 3\n");
#endif
	fprintf(stderr, "\t-g\t\t\tfirst query parameter is base DN extension\n\t\t\t\tfor this query\n");
	fprintf(stderr, "\t-S\t\t\tStrip NT domain from usernames\n");
	fprintf(stderr, "\t-K\t\t\tStrip Kerberos realm from usernames\n");
	fprintf(stderr, "\t-d\t\t\tenable debug mode\n");
	fprintf(stderr, "\n");
	fprintf(stderr, "\tIf you need to bind as a user to perform searches then use the\n\t-D binddn -w bindpasswd or -D binddn -W secretfile options\n\n");
	exit(1);
    }
/* On Windows ldap_start_tls_s is available starting from Windows XP, 
 * so we need to bind at run-time with the function entry point
 */
#ifdef _SQUID_MSWIN_
    if (use_tls) {

	HMODULE WLDAP32Handle;

	WLDAP32Handle = GetModuleHandle("wldap32");
	if ((Win32_ldap_start_tls_s = (PFldap_start_tls_s) GetProcAddress(WLDAP32Handle, LDAP_START_TLS_S)) == NULL) {
	    fprintf(stderr, PROGRAM_NAME ": ERROR: TLS (-Z) not supported on this platform.\n");
	    exit(1);
	}
    }
#endif

    while (fgets(buf, 256, stdin) != NULL) {
	int found = 0;
	if (!strchr(buf, '\n')) {
	    /* too large message received.. skip and deny */
	    fprintf(stderr, "%s: ERROR: Too large: %s\n", argv[0], buf);
	    while (fgets(buf, sizeof(buf), stdin)) {
		fprintf(stderr, "%s: ERROR: Too large..: %s\n", argv[0], buf);
		if (strchr(buf, '\n') != NULL)
		    break;
	    }
	    goto error;
	}
	user = strtok(buf, " \n");
	if (!user) {
	    fprintf(stderr, "%s: Invalid request\n", argv[0]);
	    goto error;
	}
	rfc1738_unescape(user);
	if (strip_nt_domain) {
	    char *u = strrchr(user, '\\');
	    if (!u)
		u = strrchr(user, '/');
	    if (!u)
		u = strrchr(user, '+');
	    if (u && u[1])
		user = u + 1;
	}
	if (strip_kerberos_realm) {
	    char *u = strchr(user, '@');
	    if (u != NULL) {
		*u = '\0';
	    }
	}
	if (use_extension_dn) {
	    extension_dn = strtok(NULL, " \n");
	    if (!extension_dn) {
		fprintf(stderr, "%s: Invalid request\n", argv[0]);
		goto error;
	    }
	    rfc1738_unescape(extension_dn);
	}
	while (!found && user && (group = strtok(NULL, " \n")) != NULL) {
	    rfc1738_unescape(group);

	  recover:
	    if (ld == NULL) {
#if HAS_URI_SUPPORT
		if (strstr(ldapServer, "://") != NULL) {
		    rc = ldap_initialize(&ld, ldapServer);
		    if (rc != LDAP_SUCCESS) {
			fprintf(stderr, "\nUnable to connect to LDAPURI:%s\n", ldapServer);
			break;
		    }
		} else
#endif
#if NETSCAPE_SSL
		if (sslpath) {
		    if (!sslinit && (ldapssl_client_init(sslpath, NULL) != LDAP_SUCCESS)) {
			fprintf(stderr, "\nUnable to initialise SSL with cert path %s\n",
			    sslpath);
			exit(1);
		    } else {
			sslinit++;
		    }
		    if ((ld = ldapssl_init(ldapServer, port, 1)) == NULL) {
			fprintf(stderr, "\nUnable to connect to SSL LDAP server: %s port:%d\n",
			    ldapServer, port);
			exit(1);
		    }
		} else
#endif
		if ((ld = ldap_init(ldapServer, port)) == NULL) {
		    fprintf(stderr, "\nUnable to connect to LDAP server:%s port:%d\n", ldapServer, port);
		    break;
		}
		if (connect_timeout)
		    squid_ldap_set_connect_timeout(ld, connect_timeout);

#ifdef LDAP_VERSION3
		if (version == -1) {
		    version = LDAP_VERSION2;
		}
		if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_SUCCESS) {
		    fprintf(stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
			version);
		    ldap_unbind(ld);
		    ld = NULL;
		    break;
		}
		if (use_tls) {
#ifdef LDAP_OPT_X_TLS
		    if (version != LDAP_VERSION3) {
			fprintf(stderr, "TLS requires LDAP version 3\n");
			exit(1);
		    } else if (ldap_start_tls_s(ld, NULL, NULL) != LDAP_SUCCESS) {
			fprintf(stderr, "Could not Activate TLS connection\n");
			ldap_unbind(ld);
			ld = NULL;
			break;
		    }
#else
		    fprintf(stderr, "TLS not supported with your LDAP library\n");
		    exit(1);
#endif
		}
#endif
		squid_ldap_set_timelimit(ld, timelimit);
		squid_ldap_set_referrals(ld, !noreferrals);
		squid_ldap_set_aliasderef(ld, aliasderef);
		if (binddn && bindpasswd && *binddn && *bindpasswd) {
		    rc = ldap_simple_bind_s(ld, binddn, bindpasswd);
		    if (rc != LDAP_SUCCESS) {
			fprintf(stderr, PROGRAM_NAME " WARNING, could not bind to binddn '%s'\n", ldap_err2string(rc));
			ldap_unbind(ld);
			ld = NULL;
			break;
		    }
		}
		if (debug)
		    fprintf(stderr, "Connected OK\n");
	    }
	    if (searchLDAP(ld, group, user, extension_dn) == 0) {
		found = 1;
		break;
	    } else {
		if (tryagain) {
		    tryagain = 0;
		    ldap_unbind(ld);
		    ld = NULL;
		    goto recover;
		}
	    }
	}
	if (found)
	    printf("OK\n");
	else {
	  error:
	    printf("ERR\n");
	}

	if (ld != NULL) {
	    if (!persistent || (squid_ldap_errno(ld) != LDAP_SUCCESS && squid_ldap_errno(ld) != LDAP_INVALID_CREDENTIALS)) {
		ldap_unbind(ld);
		ld = NULL;
	    } else {
		tryagain = 1;
	    }
	}
    }
    if (ld)
	ldap_unbind(ld);
    return 0;
}
Example #10
0
int
main(int argc, char **argv)
{
    char username[256];
    char password[256];
    char wstr[256];
    int err = 0;

    openlog("msnt_auth", LOG_PID, LOG_USER);
    setbuf(stdout, NULL);

    /* Read configuration file. Abort wildly if error. */
    if (OpenConfigFile() == 1)
	return 1;

    /*
     * Read denied and allowed user files.
     * If they fails, there is a serious problem.
     * Check syslog messages. Deny all users while in this state.
     * The msntauth process should then be killed.
     */
    if ((Read_denyusers() == 1) || (Read_allowusers() == 1)) {
	while (1) {
	    memset(wstr, '\0', sizeof(wstr));
	    fgets(wstr, 255, stdin);
	    puts("ERR");
	}
    }
    /*
     * Make Check_forchange() the handle for HUP signals.
     * Don't use alarms any more. I don't think it was very
     * portable between systems.
     * XXX this should be sigaction()
     */
    signal(SIGHUP, Check_forchange);

    while (1) {
	int n;
	/* Read whole line from standard input. Terminate on break. */
	memset(wstr, '\0', sizeof(wstr));
	if (fgets(wstr, 255, stdin) == NULL)
	    break;
	/* ignore this line if we didn't get the end-of-line marker */
	if (NULL == strchr(wstr, '\n')) {
	    err = 1;
	    continue;
	}
	if (err) {
	    syslog(LOG_WARNING, "oversized message");
	    goto error;
	}

	/*
	 * extract username and password.
	 * XXX is sscanf() safe?
	 */
	username[0] = '\0';
	password[0] = '\0';
	n = sscanf(wstr, "%s %[^\n]", username, password);
	if (2 != n) {
	    puts("ERR");
	    continue;
	}
	/* Check for invalid or blank entries */
	if ((username[0] == '\0') || (password[0] == '\0')) {
	    puts("ERR");
	    continue;
	}
	Checktimer();		/* Check if the user lists have changed */

	rfc1738_unescape(username);
	rfc1738_unescape(password);

	/*
	 * Check if user is explicitly denied or allowed.
	 * If user passes both checks, they can be authenticated.
	 */
	if (Check_user(username) == 1) {
	    syslog(LOG_INFO, "'%s' denied", username);
	    puts("ERR");
	} else if (QueryServers(username, password) == 0)
	    puts("OK");
	else {
	    syslog(LOG_INFO, "'%s' login failed", username);
error:
	    puts("ERR");
	}
	err = 0;
    }

    return 0;
}
Example #11
0
/***************************************************************************
  load all the variables passed to the CGI program. May have multiple variables
  with the same name and the same or different values. Takes a file parameter
  for simulating CGI invocation eg loading saved preferences.
  ***************************************************************************/
void cgi_load_variables(void)
{
	static char *line;
	char *p, *s, *tok;
	int len, i;
	FILE *f = stdin;

#ifdef DEBUG_COMMENTS
	char dummy[100]="";
	print_title(dummy);
	d_printf("<!== Start dump in cgi_load_variables() %s ==>\n",__FILE__);
#endif

	if (!content_length) {
		p = getenv("CONTENT_LENGTH");
		len = p?atoi(p):0;
	} else {
		len = content_length;
	}


	if (len > 0 && 
	    (request_post ||
	     ((s=getenv("REQUEST_METHOD")) && 
	      strequal(s,"POST")))) {
		while (len && (line=grab_line(f, &len))) {
			p = strchr_m(line,'=');
			if (!p) continue;
			
			*p = 0;
			
			variables[num_variables].name = SMB_STRDUP(line);
			variables[num_variables].value = SMB_STRDUP(p+1);

			SAFE_FREE(line);
			
			if (!variables[num_variables].name || 
			    !variables[num_variables].value)
				continue;

			plus_to_space_unescape(variables[num_variables].value);
			rfc1738_unescape(variables[num_variables].value);
			plus_to_space_unescape(variables[num_variables].name);
			rfc1738_unescape(variables[num_variables].name);

#ifdef DEBUG_COMMENTS
			printf("<!== POST var %s has value \"%s\"  ==>\n",
			       variables[num_variables].name,
			       variables[num_variables].value);
#endif
			
			num_variables++;
			if (num_variables == MAX_VARIABLES) break;
		}
	}

	fclose(stdin);
	open("/dev/null", O_RDWR);

	if ((s=query_string) || (s=getenv("QUERY_STRING"))) {
		char *saveptr;
		for (tok=strtok_r(s, "&;", &saveptr); tok;
		     tok=strtok_r(NULL, "&;", &saveptr)) {
			p = strchr_m(tok,'=');
			if (!p) continue;
			
			*p = 0;
			
			variables[num_variables].name = SMB_STRDUP(tok);
			variables[num_variables].value = SMB_STRDUP(p+1);

			if (!variables[num_variables].name ||
			    !variables[num_variables].value)
				continue;

			plus_to_space_unescape(variables[num_variables].value);
			rfc1738_unescape(variables[num_variables].value);
			plus_to_space_unescape(variables[num_variables].name);
			rfc1738_unescape(variables[num_variables].name);

#ifdef DEBUG_COMMENTS
                        printf("<!== Commandline var %s has value \"%s\"  ==>\n",
                               variables[num_variables].name,
                               variables[num_variables].value);
#endif
			num_variables++;
			if (num_variables == MAX_VARIABLES) break;
		}

	}
#ifdef DEBUG_COMMENTS
        printf("<!== End dump in cgi_load_variables() ==>\n");
#endif

	/* variables from the client are in UTF-8 - convert them
	   to our internal unix charset before use */
	for (i=0;i<num_variables;i++) {
		TALLOC_CTX *frame = talloc_stackframe();
		char *dest = NULL;
		size_t dest_len;

		convert_string_allocate(frame, CH_UTF8, CH_UNIX,
			       variables[i].name, strlen(variables[i].name),
			       &dest, &dest_len, True);
		SAFE_FREE(variables[i].name);
		variables[i].name = SMB_STRDUP(dest ? dest : "");

		dest = NULL;
		convert_string_allocate(frame, CH_UTF8, CH_UNIX,
			       variables[i].value, strlen(variables[i].value),
			       &dest, &dest_len, True);
		SAFE_FREE(variables[i].value);
		variables[i].value = SMB_STRDUP(dest ? dest : "");
		TALLOC_FREE(frame);
	}
}
Example #12
0
/*
 * The helper program receives queries on stdin, one
 * per line, and must return the result on on stdout
 */
static void
refreshCheckHandleReply(void *data, char *reply)
{
    refreshCheckState *state = data;
    refreshCheckState *next;
    int freshness = -1;
    char *log = NULL;
    MemBuf hdrs = MemBufNULL;


    debug(84, 2) ("refreshCheckHandleReply: reply=\"%s\"\n", reply);

    if (reply) {
	char *t = NULL;
	char *token = strwordtok(reply, &t);
	if (token && strcmp(token, "FRESH") == 0)
	    freshness = 0;
	else if (token && strcmp(token, "OK") == 0)
	    freshness = 0;

	while ((token = strwordtok(NULL, &t))) {
	    char *value = strchr(token, '=');
	    if (value) {
		*value++ = '\0';	/* terminate the token, and move up to the value */
		rfc1738_unescape(value);
		if (strcmp(token, "freshness") == 0)
		    freshness = atoi(value);
		else if (strcmp(token, "log") == 0)
		    log = value;
		else if (strncmp(token, "res{", 4) == 0) {
		    char *header, *t;
		    header = token + 4;
		    t = strrchr(header, '}');
		    if (!t)
			continue;
		    *t = '\0';
		    if (!hdrs.buf)
			memBufDefInit(&hdrs);
		    memBufPrintf(&hdrs, "%s: %s\r\n", header, value);
		}
	    }
	}
    }
    if (freshness >= 0) {
	if (hdrs.size) {
	    HttpReply *rep = httpReplyCreate();
	    httpHeaderParse(&rep->header, hdrs.buf, hdrs.buf + hdrs.size);
	    httpReplyUpdateOnNotModified(state->entry->mem_obj->reply, rep);
	    storeTimestampsSet(state->entry);
	    if (!httpHeaderHas(&rep->header, HDR_DATE)) {
		state->entry->timestamp = squid_curtime;
		state->entry->expires = squid_curtime + freshness;
	    } else if (freshness) {
		state->entry->expires = squid_curtime + freshness;
	    }
	    httpReplyDestroy(rep);
	    storeUpdate(state->entry, NULL);
	} else {
	    state->entry->timestamp = squid_curtime;
	    state->entry->expires = squid_curtime + freshness;
	}
    }
    if (hdrs.buf)
	memBufClean(&hdrs);
    dlinkDelete(&state->list, &state->def->queue);
    do {
	cbdataUnlock(state->def);
	state->def = NULL;

	if (state->callback && cbdataValid(state->callback_data))
	    state->callback(state->callback_data, freshness >= 0, log);
	cbdataUnlock(state->callback_data);
	state->callback_data = NULL;

	next = state->queue;
	cbdataFree(state);
	state = next;
    } while (state);
}
int
main(int argc, char **argv)
{
    char buf[1024];
    char *user, *passwd;
    char *ldapServer = NULL;
    LDAP *ld = NULL;
    int tryagain;
    int port = LDAP_PORT;

    setbuf(stdout, NULL);

    while (argc > 1 && argv[1][0] == '-') {
	const char *value = "";
	char option = argv[1][1];
	switch (option) {
	case 'P':
	case 'R':
	case 'z':
	case 'Z':
	case 'd':
	case 'O':
	    break;
	default:
	    if (strlen(argv[1]) > 2) {
		value = argv[1] + 2;
	    } else if (argc > 2) {
		value = argv[2];
		argv++;
		argc--;
	    } else
		value = "";
	    break;
	}
	argv++;
	argc--;
	switch (option) {
	case 'H':
#if !HAS_URI_SUPPORT
	    fprintf(stderr, "ERROR: Your LDAP library does not have URI support\n");
	    exit(1);
#endif
	    /* Fall thru to -h */
	case 'h':
	    if (ldapServer) {
		int len = strlen(ldapServer) + 1 + strlen(value) + 1;
		char *newhost = malloc(len);
		snprintf(newhost, len, "%s %s", ldapServer, value);
		free(ldapServer);
		ldapServer = newhost;
	    } else {
		ldapServer = strdup(value);
	    }
	    break;
	case 'b':
	    basedn = value;
	    break;
	case 'f':
	    searchfilter = value;
	    break;
	case 'u':
	    userattr = value;
	    break;
	case 'U':
	    passwdattr = value;
	    break;
	case 's':
	    if (strcmp(value, "base") == 0)
		searchscope = LDAP_SCOPE_BASE;
	    else if (strcmp(value, "one") == 0)
		searchscope = LDAP_SCOPE_ONELEVEL;
	    else if (strcmp(value, "sub") == 0)
		searchscope = LDAP_SCOPE_SUBTREE;
	    else {
		fprintf(stderr, PROGRAM_NAME ": ERROR: Unknown search scope '%s'\n", value);
		exit(1);
	    }
	    break;
	case 'E':
#if defined(NETSCAPE_SSL)
	    sslpath = value;
	    if (port == LDAP_PORT)
		port = LDAPS_PORT;
#else
	    fprintf(stderr, PROGRAM_NAME " ERROR: -E unsupported with this LDAP library\n");
	    exit(1);
#endif
	    break;
	case 'c':
	    connect_timeout = atoi(value);
	    break;
	case 't':
	    timelimit = atoi(value);
	    break;
	case 'a':
	    if (strcmp(value, "never") == 0)
		aliasderef = LDAP_DEREF_NEVER;
	    else if (strcmp(value, "always") == 0)
		aliasderef = LDAP_DEREF_ALWAYS;
	    else if (strcmp(value, "search") == 0)
		aliasderef = LDAP_DEREF_SEARCHING;
	    else if (strcmp(value, "find") == 0)
		aliasderef = LDAP_DEREF_FINDING;
	    else {
		fprintf(stderr, PROGRAM_NAME ": ERROR: Unknown alias dereference method '%s'\n", value);
		exit(1);
	    }
	    break;
	case 'D':
	    binddn = value;
	    break;
	case 'w':
	    bindpasswd = value;
	    break;
	case 'W':
	    readSecret(value);
	    break;
	case 'P':
	    persistent = !persistent;
	    break;
	case 'O':
	    bind_once = !bind_once;
	    break;
	case 'p':
	    port = atoi(value);
	    break;
	case 'R':
	    noreferrals = !noreferrals;
	    break;
#ifdef LDAP_VERSION3
	case 'v':
	    switch (atoi(value)) {
	    case 2:
		version = LDAP_VERSION2;
		break;
	    case 3:
		version = LDAP_VERSION3;
		break;
	    default:
		fprintf(stderr, "Protocol version should be 2 or 3\n");
		exit(1);
	    }
	    break;
	case 'Z':
	    if (version == LDAP_VERSION2) {
		fprintf(stderr, "TLS (-Z) is incompatible with version %d\n",
		    version);
		exit(1);
	    }
	    version = LDAP_VERSION3;
	    use_tls = 1;
	    break;
#endif
	case 'd':
	    debug++;
	    break;
	default:
	    fprintf(stderr, PROGRAM_NAME ": ERROR: Unknown command line option '%c'\n", option);
	    exit(1);
	}
    }

    while (argc > 1) {
	char *value = argv[1];
	if (ldapServer) {
	    int len = strlen(ldapServer) + 1 + strlen(value) + 1;
	    char *newhost = malloc(len);
	    snprintf(newhost, len, "%s %s", ldapServer, value);
	    free(ldapServer);
	    ldapServer = newhost;
	} else {
	    ldapServer = strdup(value);
	}
	argc--;
	argv++;
    }
    if (!ldapServer)
	ldapServer = strdup("localhost");

    if (!basedn) {
	fprintf(stderr, "Usage: " PROGRAM_NAME " -b basedn [options] [ldap_server_name[:port]]...\n\n");
	fprintf(stderr, "\t-b basedn (REQUIRED)\tbase dn under which to search\n");
	fprintf(stderr, "\t-f filter\t\tsearch filter to locate user DN\n");
	fprintf(stderr, "\t-u userattr\t\tusername DN attribute\n");
	fprintf(stderr, "\t-s base|one|sub\t\tsearch scope\n");
	fprintf(stderr, "\t-D binddn\t\tDN to bind as to perform searches\n");
	fprintf(stderr, "\t-w bindpasswd\t\tpassword for binddn\n");
	fprintf(stderr, "\t-W secretfile\t\tread password for binddn from file secretfile\n");
#if HAS_URI_SUPPORT
	fprintf(stderr, "\t-H URI\t\t\tLDAPURI (defaults to ldap://localhost)\n");
#endif
	fprintf(stderr, "\t-h server\t\tLDAP server (defaults to localhost)\n");
	fprintf(stderr, "\t-p port\t\t\tLDAP server port\n");
	fprintf(stderr, "\t-P\t\t\tpersistent LDAP connection\n");
#if defined(NETSCAPE_SSL)
	fprintf(stderr, "\t-E sslcertpath\t\tenable LDAP over SSL\n");
#endif
	fprintf(stderr, "\t-c timeout\t\tconnect timeout\n");
	fprintf(stderr, "\t-t timelimit\t\tsearch time limit\n");
	fprintf(stderr, "\t-R\t\t\tdo not follow referrals\n");
	fprintf(stderr, "\t-a never|always|search|find\n\t\t\t\twhen to dereference aliases\n");
#ifdef LDAP_VERSION3
	fprintf(stderr, "\t-v 2|3\t\t\tLDAP version\n");
	fprintf(stderr, "\t-Z\t\t\tTLS encrypt the LDAP connection, requires LDAP version 3\n");
#endif
	fprintf(stderr, "\n");
	fprintf(stderr, "\tIf no search filter is specified, then the dn <userattr>=user,basedn\n\twill be used (same as specifying a search filter of '<userattr>=',\n\tbut quicker as as there is no need to search for the user DN)\n\n");
	fprintf(stderr, "\tIf you need to bind as a user to perform searches then use the\n\t-D binddn -w bindpasswd or -D binddn -W secretfile options\n\n");
	exit(1);
    }
/* On Windows ldap_start_tls_s is available starting from Windows XP, 
 * so we need to bind at run-time with the function entry point
 */
#ifdef _SQUID_MSWIN_
    if (use_tls) {

	HMODULE WLDAP32Handle;

	WLDAP32Handle = GetModuleHandle("wldap32");
	if ((Win32_ldap_start_tls_s = (PFldap_start_tls_s) GetProcAddress(WLDAP32Handle, LDAP_START_TLS_S)) == NULL) {
	    fprintf(stderr, PROGRAM_NAME ": ERROR: TLS (-Z) not supported on this platform.\n");
	    exit(1);
	}
    }
#endif

    while (fgets(buf, sizeof(buf), stdin) != NULL) {
	user = strtok(buf, " \r\n");
	passwd = strtok(NULL, "\r\n");

	if (!user || !passwd || !passwd[0]) {
	    printf("ERR\n");
	    continue;
	}
	rfc1738_unescape(user);
	rfc1738_unescape(passwd);
	if (!validUsername(user)) {
	    printf("ERR No such user\n");
	    continue;
	}
	tryagain = (ld != NULL);
      recover:
	if (ld == NULL && persistent)
	    ld = open_ldap_connection(ldapServer, port);
	if (checkLDAP(ld, user, passwd, ldapServer, port) != 0) {
	    if (tryagain && squid_ldap_errno(ld) != LDAP_INVALID_CREDENTIALS) {
		tryagain = 0;
		ldap_unbind(ld);
		ld = NULL;
		goto recover;
	    }
	    printf("ERR %s\n", ldap_err2string(squid_ldap_errno(ld)));
	} else {
	    printf("OK\n");
	}
	if (ld && (squid_ldap_errno(ld) != LDAP_SUCCESS && squid_ldap_errno(ld) != LDAP_INVALID_CREDENTIALS)) {
	    ldap_unbind(ld);
	    ld = NULL;
	}
    }
    if (ld)
	ldap_unbind(ld);
    return 0;
}
Example #14
0
int
main(int argc, char *argv[])
{
    pam_handle_t *pamh = NULL;
    int retval = PAM_SUCCESS;
    char *user;
    /* char *password; */
    char buf[BUFSIZE];
    time_t pamh_created = 0;
    int ttl = DEFAULT_SQUID_PAM_TTL;
    char *service = DEFAULT_SQUID_PAM_SERVICE;
    int no_acct_mgmt = 0;

    /* make standard output line buffered */
    setvbuf(stdout, NULL, _IOLBF, 0);

    while (1) {
	int ch = getopt(argc, argv, "1n:t:o");
	switch (ch) {
	case -1:
		goto start;
	case 'n':
		service = optarg;
		break;
	case 't':
		ttl = atoi(optarg);
		break;
	case '1':
		ttl = 0;
		break;
	case 'o':
		no_acct_mgmt = 1;
		break;
	default:
		fprintf(stderr, "Unknown getopt value '%c'\n", ch);
		usage(argv[0]);
		exit(1);
	}
    }
start:
    if (optind < argc) {
	fprintf(stderr, "Unknown option '%s'\n", argv[optind]);
	usage(argv[0]);
	exit(1);
    }

    while (fgets(buf, BUFSIZE, stdin)) {
	user = buf;
	password = strchr(buf, '\n');
	if (!password) {
	    fprintf(stderr, "authenticator: Unexpected input '%s'\n", buf);
	    goto error;
	}
	*password = '******';
	password = strchr(buf, ' ');
	if (!password) {
	    fprintf(stderr, "authenticator: Unexpected input '%s'\n", buf);
	    goto error;
	}
	*password++ = '\0';
	rfc1738_unescape(user);
	rfc1738_unescape(password);
	conv.appdata_ptr = (char *) password;	/* from buf above. not allocated */

	if (ttl == 0) {
	    /* Create PAM connection */
	    retval = pam_start(service, user, &conv, &pamh);
	    if (retval != PAM_SUCCESS) {
		fprintf(stderr, "ERROR: failed to create PAM authenticator\n");
		goto error;
	    }
	} else if (!pamh || (time(NULL) - pamh_created) >= ttl || pamh_created > time(NULL)) {
	    /* Close previous PAM connection */
	    if (pamh) {
		retval = pam_end(pamh, retval);
		if (retval != PAM_SUCCESS) {
		    fprintf(stderr, "WARNING: failed to release PAM authenticator\n");
		}
		pamh = NULL;
	    }
	    /* Initialize persistent PAM connection */
	    retval = pam_start(service, "squid@", &conv, &pamh);
	    if (retval != PAM_SUCCESS) {
		fprintf(stderr, "ERROR: failed to create PAM authenticator\n");
		goto error;
	    }
	    pamh_created = time(NULL);
	}
	/* Authentication */
	retval = PAM_SUCCESS;
	if (ttl != 0) {
	    if (retval == PAM_SUCCESS)
		retval = pam_set_item(pamh, PAM_USER, user);
	    if (retval == PAM_SUCCESS)
		retval = pam_set_item(pamh, PAM_CONV, &conv);
	}
	if (retval == PAM_SUCCESS)
	    retval = pam_authenticate(pamh, 0);
	if (retval == PAM_SUCCESS && !no_acct_mgmt)
	    retval = pam_acct_mgmt(pamh, 0);
	if (retval == PAM_SUCCESS) {
	    fprintf(stdout, "OK\n");
	} else {
error:
	    fprintf(stdout, "ERR\n");
	}
	/* cleanup */
	retval = PAM_SUCCESS;
#ifdef PAM_AUTHTOK
	if (ttl != 0) {
	    if (retval == PAM_SUCCESS)
		retval = pam_set_item(pamh, PAM_AUTHTOK, NULL);
	}
#endif
	if (ttl == 0 || retval != PAM_SUCCESS) {
	    retval = pam_end(pamh, retval);
	    if (retval != PAM_SUCCESS) {
		fprintf(stderr, "WARNING: failed to release PAM authenticator\n");
	    }
	    pamh = NULL;
	}
    }

    if (pamh) {
	retval = pam_end(pamh, retval);
	if (retval != PAM_SUCCESS) {
	    pamh = NULL;
	    fprintf(stderr, "ERROR: failed to release PAM authenticator\n");
	}
    }
    return 0;
}
Example #15
0
int
main (int argc, char *argv[])
{
    FILE *FH;
    char *filename = NULL;
    char *program_name = argv[0];
    char *cp;
    char *username, *address;
    char line[BUFSIZE];
    struct ip_user_dict *current_entry;
    int ch;

    setvbuf (stdout, NULL, _IOLBF, 0);
    while ((ch = getopt (argc, argv, "f:")) != -1) {
        switch (ch) {
        case 'f':
            filename = optarg;
            break;
        default:
            usage (program_name);
            exit (1);
        }
    }
    if (filename == NULL) {
        usage (program_name);
        exit(1);
    }
    FH = fopen (filename, "r");
    current_entry = load_dict (FH);

    while (fgets (line, sizeof (line), stdin)) {
        if ((cp = strchr (line, '\n')) == NULL) {
            /* too large message received.. skip and deny */
            fprintf(stderr, "%s: ERROR: Too large: %s\n", argv[0], line);
            while (fgets(line, sizeof(line), stdin)) {
                fprintf(stderr, "%s: ERROR: Too large..: %s\n", argv[0], line);
                if (strchr(line, '\n') != NULL)
                    break;
            }
            goto error;
        }
        *cp = '\0';
        address = strtok (line, " \t");
        username = strtok (NULL, " \t");
        if (!address || !username) {
            fprintf (stderr, "%s: unable to read tokens\n", argv[0]);
            goto error;
        }
        rfc1738_unescape(address);
        rfc1738_unescape(username);
#ifdef DEBUG
        printf ("result: %d\n",
                dict_lookup (current_entry, username, address));
#endif
        if ((dict_lookup (current_entry, username, address)) != 0) {
            printf ("OK\n");
        } else {
error:
            printf ("ERR\n");
        }
    }


    fclose (FH);
    return 0;
}
Example #16
0
int
main(int argc, char *argv[])
{
    char *user, *suser, *p;
    char buf[BUFSIZE];
    char **grents = NULL;
    int check_pw = 0, ch, ngroups = 0, i, j = 0, strip_dm = 0;

    /* make standard output line buffered */
    setvbuf(stdout, NULL, _IOLBF, 0);

    /* get user options */
    while ((ch = getopt(argc, argv, "spg:")) != -1) {
  	switch (ch) {
	case 's':
	    strip_dm = 1;
	    break;
	case 'p':
	    check_pw = 1;
	    break;
	case 'g':
	    grents = (char **) realloc(grents, sizeof(*grents) * (ngroups + 1));
	    grents[ngroups++] = optarg;
	    break;
	case '?':
	    if (isprint(optopt)) {
		fprintf(stderr, "Unknown option '-%c'.\n", optopt);
	    } else {
		fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
	    }

	default:
	    usage(argv[0]);
	    exit(1);
	}
    }
    if (optind < argc) {
	fprintf(stderr, "FATAL: Unknown option '%s'\n", argv[optind]);
	usage(argv[0]);
	exit(1);
    }
    while (fgets(buf, sizeof(buf), stdin)) {
	j = 0;
	if ((p = strchr(buf, '\n')) == NULL) {
	    /* too large message received.. skip and deny */
	    fprintf(stderr, "ERROR: %s: Too large: %s\n", argv[0], buf);
	    while (fgets(buf, sizeof(buf), stdin)) {
		fprintf(stderr, "ERROR: %s: Too large..: %s\n", argv[0], buf);
		if (strchr(buf, '\n') != NULL)
		    break;
	    }
	    goto error;
	}
	*p = '\0';
	if ((p = strtok(buf, " ")) == NULL) {
	    goto error;
	} else {
	    user = p;
	    rfc1738_unescape(user);
	    if (user && strip_dm) {
		suser = strchr(user, '\\');
		if (!suser) suser = strchr(user, '/');
		if (suser && suser[1]) user = suser + 1;
	    }
	    /* check groups supplied by Squid */
	    while ((p = strtok(NULL, " ")) != NULL) {
		rfc1738_unescape(p);
		if (check_pw == 1)
		    j += validate_user_pw(user, p);
		j += validate_user_gr(user, p);
	    }
	}

	/* check groups supplied on the command line */
	for (i = 0; i < ngroups; i++) {
	    if (check_pw == 1) {
		j += validate_user_pw(user, grents[i]);
	    }
	    j += validate_user_gr(user, grents[i]);
	}

	if (j > 0) {
	    printf("OK\n");
	} else {
error:
	    printf("ERR\n");
	}
    }
    return 0;
}
int
main(int argc, char *argv[])
{
	char line[8192];
	char *username, *password;
#if SASL_VERSION_MAJOR < 2
	const char *errstr;
#endif

	int rc;
        sasl_conn_t *conn = NULL;

	/* make standard output line buffered */
	setvbuf(stdout, NULL, _IOLBF, 0);

	rc = sasl_server_init( NULL, APP_NAME_SASL );

	if ( rc != SASL_OK ) {
		fprintf( stderr, "error %d %s\n", rc, sasl_errstring(rc, NULL, NULL ));
		fprintf( stdout, "ERR\n" );
		return 1;
	}

	#if SASL_VERSION_MAJOR < 2
	rc = sasl_server_new( APP_NAME_SASL, NULL, NULL, NULL, 0, &conn );
	#else
	rc = sasl_server_new( APP_NAME_SASL, NULL, NULL, NULL, NULL, NULL, 0, &conn );
	#endif

	if ( rc != SASL_OK ) {
		fprintf( stderr, "error %d %s\n", rc, sasl_errstring(rc, NULL, NULL ));
		fprintf( stdout, "ERR\n" );
		return 1;
	}

	while ( fgets( line, sizeof( line ), stdin )) {
		username = &line[0];
		password = strchr( line, '\n' );
		if ( !password) {
			fprintf( stderr, "authenticator: Unexpected input '%s'\n", line );
			fprintf( stdout, "ERR\n" );
			continue;
		}
		*password = '******';
		password = strchr ( line, ' ' );
		if ( !password) {
			fprintf( stderr, "authenticator: Unexpected input '%s'\n", line );
			fprintf( stdout, "ERR\n" );
			continue;
		}
		*password++ = '\0';

		rfc1738_unescape(username);
		rfc1738_unescape(password);

		#if SASL_VERSION_MAJOR < 2
		rc = sasl_checkpass(conn, username, strlen(username), password, strlen(password), &errstr);
		#else
		rc = sasl_checkpass(conn, username, strlen(username), password, strlen(password));
		#endif

		if ( rc != SASL_OK ) {
			#if SASL_VERSION_MAJOR < 2
			if ( errstr ) {
				fprintf( stderr, "errstr %s\n", errstr );
			}
			if ( rc != SASL_BADAUTH ) {
				fprintf( stderr, "error %d %s\n", rc, sasl_errstring(rc, NULL, NULL ));
			}
			#endif
			fprintf( stdout, "ERR\n" );
		}
		else {
			fprintf( stdout, "OK\n" );
		}

	}

        sasl_dispose( &conn );
        sasl_done();

	return 0;
}