s4-auth Add function to obtain any user's session_info from a given LDB
[samba.git] / source4 / auth / pyauth.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2008
4    
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9    
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14    
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <Python.h>
20 #include "includes.h"
21 #include "libcli/util/pyerrors.h"
22 #include "param/param.h"
23 #include "pyauth.h"
24 #include "pyldb.h"
25 #include "auth/system_session_proto.h"
26 #include "auth/session.h"
27 #include "param/pyparam.h"
28 #include "libcli/security/security.h"
29
30 static PyTypeObject PyAuthSession = {
31         .tp_name = "AuthSession",
32         .tp_basicsize = sizeof(py_talloc_Object),
33         .tp_flags = Py_TPFLAGS_DEFAULT,
34 };
35
36 PyObject *PyAuthSession_FromSession(struct auth_session_info *session)
37 {
38         return py_talloc_reference(&PyAuthSession, session);
39 }
40
41 static PyObject *py_system_session(PyObject *module, PyObject *args)
42 {
43         PyObject *py_lp_ctx = Py_None;
44         struct loadparm_context *lp_ctx = NULL;
45         struct auth_session_info *session;
46         TALLOC_CTX *mem_ctx;
47         if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
48                 return NULL;
49
50         mem_ctx = talloc_new(NULL);
51         if (mem_ctx == NULL) {
52                 PyErr_NoMemory();
53                 return NULL;
54         }
55
56         lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
57         if (lp_ctx == NULL) {
58                 talloc_free(mem_ctx);
59                 return NULL;
60         }
61
62         session = system_session(lp_ctx);
63
64         talloc_free(mem_ctx);
65
66         return PyAuthSession_FromSession(session);
67 }
68
69
70 static PyObject *py_admin_session(PyObject *module, PyObject *args)
71 {
72         PyObject *py_lp_ctx;
73         PyObject *py_sid;
74         struct loadparm_context *lp_ctx = NULL;
75         struct auth_session_info *session;
76         struct dom_sid *domain_sid = NULL;
77         TALLOC_CTX *mem_ctx;
78
79         if (!PyArg_ParseTuple(args, "OO", &py_lp_ctx, &py_sid))
80                 return NULL;
81
82         mem_ctx = talloc_new(NULL);
83         if (mem_ctx == NULL) {
84                 PyErr_NoMemory();
85                 return NULL;
86         }
87
88         lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
89         if (lp_ctx == NULL) {
90                 talloc_free(mem_ctx);
91                 return NULL;
92         }
93
94         domain_sid = dom_sid_parse_talloc(mem_ctx, PyString_AsString(py_sid));
95         if (domain_sid == NULL) {
96                 PyErr_Format(PyExc_RuntimeError, "Unable to parse sid %s", 
97                                          PyString_AsString(py_sid));
98                 talloc_free(mem_ctx);
99                 return NULL;
100         }
101         session = admin_session(NULL, lp_ctx, domain_sid);
102         talloc_free(mem_ctx);
103
104         return PyAuthSession_FromSession(session);
105 }
106
107 static PyObject *py_user_session(PyObject *module, PyObject *args, PyObject *kwargs)
108 {
109         NTSTATUS nt_status;
110         struct auth_session_info *session;
111         TALLOC_CTX *mem_ctx;
112         const char * const kwnames[] = { "ldb", "lp_ctx", "principal", "dn", "session_info_flags" };
113         struct ldb_context *ldb_ctx;
114         PyObject *py_ldb = Py_None;
115         PyObject *py_dn = Py_None;
116         PyObject *py_lp_ctx = Py_None;
117         struct loadparm_context *lp_ctx = NULL;
118         struct ldb_dn *user_dn;
119         char *principal = NULL;
120         int session_info_flags; /* This is an int, because that's what
121                                  * we need for the python
122                                  * PyArg_ParseTupleAndKeywords */
123
124         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OzOi",
125                                          discard_const_p(char *, kwnames),
126                                          &py_ldb, &py_lp_ctx, &principal, &py_dn, &session_info_flags)) {
127                 return NULL;
128         }
129
130         mem_ctx = talloc_new(NULL);
131         if (mem_ctx == NULL) {
132                 PyErr_NoMemory();
133                 return NULL;
134         }
135
136         ldb_ctx = PyLdb_AsLdbContext(py_ldb);
137
138         if (py_dn == Py_None) {
139                 user_dn = NULL;
140         } else {
141                 if (!PyObject_AsDn(ldb_ctx, py_dn, ldb_ctx, &user_dn)) {
142                         talloc_free(mem_ctx);
143                         return NULL;
144                 }
145         }
146
147         lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
148         if (lp_ctx == NULL) {
149                 talloc_free(mem_ctx);
150                 return NULL;
151         }
152
153         nt_status = authsam_get_session_info_principal(mem_ctx, lp_ctx, ldb_ctx, principal, user_dn,
154                                                        session_info_flags, &session);
155         if (!NT_STATUS_IS_OK(nt_status)) {
156                 talloc_free(mem_ctx);
157                 PyErr_NTSTATUS_IS_ERR_RAISE(nt_status);
158         }
159
160         talloc_steal(NULL, session);
161         talloc_free(mem_ctx);
162
163         return PyAuthSession_FromSession(session);
164 }
165
166 static PyMethodDef py_auth_methods[] = {
167         { "system_session", (PyCFunction)py_system_session, METH_VARARGS, NULL },
168         { "admin_session", (PyCFunction)py_admin_session, METH_VARARGS, NULL },
169         { "user_session", (PyCFunction)py_user_session, METH_VARARGS, NULL },
170         { NULL },
171 };
172
173 void initauth(void)
174 {
175         PyObject *m;
176
177         PyAuthSession.tp_base = PyTalloc_GetObjectType();
178         if (PyAuthSession.tp_base == NULL)
179                 return;
180
181         if (PyType_Ready(&PyAuthSession) < 0)
182                 return;
183
184         m = Py_InitModule3("auth", py_auth_methods,
185                                            "Authentication and authorization support.");
186         if (m == NULL)
187                 return;
188
189         Py_INCREF(&PyAuthSession);
190         PyModule_AddObject(m, "AuthSession", (PyObject *)&PyAuthSession);
191 }