1 // Copyright (c) 1999-2018 David Muse
2 // See the file COPYING for more information
3 
4 #include <sqlrelay/sqlrserver.h>
5 
6 #include <rudiments/domnode.h>
7 #include <rudiments/process.h>
8 #include <rudiments/stdio.h>
9 //#define DEBUG_MESSAGES 1
10 #include <rudiments/debugprint.h>
11 
12 #include <config.h>
13 
14 #ifndef SQLRELAY_ENABLE_SHARED
15 	extern "C" {
16 		#include "sqlrauthdeclarations.cpp"
17 	}
18 #endif
19 
20 class sqlrauthplugin {
21 	public:
22 		sqlrauth	*au;
23 		dynamiclib	*dl;
24 };
25 
26 class sqlrauthsprivate {
27 	friend class sqlrauths;
28 	private:
29 		sqlrservercontroller	*_cont;
30 
31 		singlylinkedlist< sqlrauthplugin * >	_llist;
32 };
33 
sqlrauths(sqlrservercontroller * cont)34 sqlrauths::sqlrauths(sqlrservercontroller *cont) {
35 	debugFunction();
36 	pvt=new sqlrauthsprivate;
37 	pvt->_cont=cont;
38 }
39 
~sqlrauths()40 sqlrauths::~sqlrauths() {
41 	debugFunction();
42 	unload();
43 	delete pvt;
44 }
45 
load(domnode * parameters,sqlrpwdencs * sqlrpe)46 bool sqlrauths::load(domnode *parameters, sqlrpwdencs *sqlrpe) {
47 	debugFunction();
48 
49 	unload();
50 
51 	// run through each set of auths
52 	for (domnode *auth=parameters->getFirstTagChild("auth");
53 			!auth->isNullNode();
54 			auth=auth->getNextTagSibling("auth")) {
55 
56 		debugPrintf("loading auth ...\n");
57 
58 		// load password encryption
59 		loadAuth(auth,sqlrpe);
60 	}
61 	return true;
62 }
63 
unload()64 void sqlrauths::unload() {
65 	debugFunction();
66 	for (singlylinkedlistnode< sqlrauthplugin * > *node=
67 						pvt->_llist.getFirst();
68 						node; node=node->getNext()) {
69 		sqlrauthplugin	*sqlrap=node->getValue();
70 		delete sqlrap->au;
71 		delete sqlrap->dl;
72 		delete sqlrap;
73 	}
74 	pvt->_llist.clear();
75 }
76 
loadAuth(domnode * auth,sqlrpwdencs * sqlrpe)77 void sqlrauths::loadAuth(domnode *auth, sqlrpwdencs *sqlrpe) {
78 	debugFunction();
79 
80 	// get the auth name
81 	const char	*module=auth->getAttributeValue("module");
82 	if (!charstring::length(module)) {
83 		// try "file", that's what it used to be called
84 		module=auth->getAttributeValue("file");
85 		if (!charstring::length(module)) {
86 			// fall back to default if no module is specified
87 			module="default";
88 		}
89 	}
90 
91 	debugPrintf("loading auth: %s\n",module);
92 
93 #ifdef SQLRELAY_ENABLE_SHARED
94 	// load the password encryption module
95 	stringbuffer	modulename;
96 	modulename.append(pvt->_cont->getPaths()->getLibExecDir());
97 	modulename.append(SQLR);
98 	modulename.append("auth_");
99 	modulename.append(module)->append(".")->append(SQLRELAY_MODULESUFFIX);
100 	dynamiclib	*dl=new dynamiclib();
101 	if (!dl->open(modulename.getString(),true,true)) {
102 		stdoutput.printf("failed to load auth module: %s\n",module);
103 		char	*error=dl->getError();
104 		stdoutput.printf("%s\n",(error)?error:"");
105 		delete[] error;
106 		delete dl;
107 		return;
108 	}
109 
110 	// load the password encryption itself
111 	stringbuffer	functionname;
112 	functionname.append("new_sqlrauth_")->append(module);
113 	sqlrauth *(*newAuth)(sqlrservercontroller *,
114 					sqlrauths *,
115 					sqlrpwdencs *,
116 					domnode *)=
117 			(sqlrauth *(*)(sqlrservercontroller *,
118 					sqlrauths *,
119 					sqlrpwdencs *,
120 					domnode *))
121 				dl->getSymbol(functionname.getString());
122 	if (!newAuth) {
123 		stdoutput.printf("failed to load auth: %s\n",module);
124 		char	*error=dl->getError();
125 		stdoutput.printf("%s\n",(error)?error:"");
126 		delete[] error;
127 		dl->close();
128 		delete dl;
129 		return;
130 	}
131 	sqlrauth	*au=(*newAuth)(pvt->_cont,this,sqlrpe,auth);
132 
133 #else
134 
135 	dynamiclib	*dl=NULL;
136 	sqlrauth	*au;
137 	#include "sqlrauthassignments.cpp"
138 	{
139 		au=NULL;
140 	}
141 #endif
142 
143 	// add the plugin to the list
144 	sqlrauthplugin	*sqlrap=new sqlrauthplugin;
145 	sqlrap->au=au;
146 	sqlrap->dl=dl;
147 	pvt->_llist.append(sqlrap);
148 }
149 
auth(sqlrcredentials * cred)150 const char *sqlrauths::auth(sqlrcredentials *cred) {
151 	debugFunction();
152 	if (!cred) {
153 		return NULL;
154 	}
155 	for (singlylinkedlistnode< sqlrauthplugin * > *node=
156 						pvt->_llist.getFirst();
157 						node; node=node->getNext()) {
158 		const char	*autheduser=node->getValue()->au->auth(cred);
159 		if (autheduser) {
160 			return autheduser;
161 		}
162 	}
163 	return NULL;
164 }
165 
endSession()166 void sqlrauths::endSession() {
167 	// nothing for now, maybe in the future
168 }
169