/*
 *(c) 2003, visigoth <visigoth@securitycentric.com>
 * This source code is distributed under a BSD license,
 * please see the LICENSE file for details
 *
 * MssqlStorProcPerm.java
 *
 */

import com.securitycentric.metacoretex.interfaces.*;
import com.securitycentric.metacoretex.lib.*;

import java.sql.*;
import java.util.*;
import java.io.*;

/**
 *
 * @author  visigoth
 */
public class MssqlStorProcPerm extends AbstractDatabaseProbe {
    
    /** Creates a new instance of MssqlStorProcPerm */
    public MssqlStorProcPerm() {
        
        setName("MSSQL Stored Procedures");
        setFamily("MS SQL");
        setVersion("$Id: MssqlStorProcPerm.java,v 1.4 2003/09/21 22:44:11 visigoth_6 Exp $");
        setProbeId(23);
        setCopyright("(c) 2003, visigoth <visigoth@securitycentric.com>");
        
        addDepends("mssql/connection");
        addOption("mssql_proc_file",System.getProperty("user.dir")+"/conf/mssql_procs.txt");
        
        setReport("Permissions for dangerous stored procedures:\n"+
                  "================================================\n");
        
        setHelp("This probe checks permissions on \"dangerous\" stored procedures. "+
                "It will only be capable of doing so if the JDBC Connection "+
                "stored in mssql/connection has sufficient privelages\n"+
                "Options:\n\n"+
                "mssql_proc_file - a list of dangerous stored procedures\n");
    }
    
    public void probe() throws ProbeException {
        
        try {
            
            if (! kbHas("mssql/connection"))
                return;
            
            fillVector();

            con = (Connection) kbGet("mssql/connection");
            
            PreparedStatement stmt = con.prepareStatement("select sysusers.name as uname from sysobjects INNER JOIN syspermissions on syspermissions.id = sysobjects.id INNER JOIN sysusers on sysusers.uid = syspermissions.grantee WHERE sysobjects.name=? order by uname;");

            Iterator i = procVect.iterator();
            while (i.hasNext()) {
                String storProc = (String)i.next();
                addReport("\n"+storProc+":");

                stmt.setString(1,storProc);
                res = stmt.executeQuery();

                setReportable(true);
            
                while (res.next()) {
                    String uname = res.getString("uname");
                    if (uname != null) {
                        addReport("\t"+uname);
                        if (uname.matches("public"))
                            setSeverity(3);
                    }
                }
            }

        } catch (SQLException se) {
            throw(new ProbeException("Lack of Permission? " + se.getMessage()));
        }
    }

    public void fillVector() throws ProbeException{

        procVect = new Vector();

        try {

            BufferedReader br = new BufferedReader(new FileReader(getOption("mssql_proc_file")));
            String line;
            while ((line = br.readLine()) != null) {

                if (line.startsWith("#"))
                    continue;

                procVect.add(line.trim());
            }

        } catch (FileNotFoundException fe) {
            throw(new ProbeException("Couldn't find file: " + getOption("mssql_proc_file")));
        } catch (IOException ie) {
            throw(new ProbeException(ie.getMessage()));
        }
    }

    Connection con;
    ResultSet res;
    Vector procVect;
}
