Added name_to_sid and sid_to_name functions.
[samba.git] / source / python / py_winbind.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    Python wrapper for winbind client functions.
5
6    Copyright (C) Tim Potter      2002
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "Python.h"
25
26 /* 
27  * Exceptions raised by this module 
28  */
29
30 PyObject *winbind_error;        /* A winbind call returned WINBINDD_ERROR */
31
32 /* Prototypes from common.h */
33
34 NSS_STATUS winbindd_request(int req_type, 
35                             struct winbindd_request *request,
36                             struct winbindd_response *response);
37
38 /* FIXME: grr this needs to be a fn in a library somewhere */
39
40 static BOOL parse_domain_user(const char *domuser, fstring domain, 
41                               fstring user)
42 {
43         char *p = strchr(domuser,*lp_winbind_separator());
44
45         if (!(p || lp_winbind_use_default_domain()))
46                 return False;
47         
48         if(!p && lp_winbind_use_default_domain()) {
49                 fstrcpy(user, domuser);
50                 fstrcpy(domain, lp_workgroup());
51         } else {
52                 fstrcpy(user, p+1);
53                 fstrcpy(domain, domuser);
54                 domain[PTR_DIFF(p, domuser)] = 0;
55         }
56         strupper(domain);
57         return True;
58 }
59
60 /*
61  * Name <-> SID conversion
62  */
63
64 /* Convert a name to a sid */
65
66 static PyObject *winbind_name_to_sid(PyObject *self, PyObject *args)
67
68 {
69         struct winbindd_request request;
70         struct winbindd_response response;
71         PyObject *result;
72         char *name, *p;
73
74         if (!PyArg_ParseTuple(args, "s", &name))
75                 return NULL;
76
77         ZERO_STRUCT(request);
78         ZERO_STRUCT(response);
79
80         /* FIXME: use winbind separator */
81
82         if ((p = strchr(name, '\\'))) {
83                 *p = 0;
84                 fstrcpy(request.data.name.dom_name, name);
85                 fstrcpy(request.data.name.name, p + 1);
86         } else {
87                 fstrcpy(request.data.name.dom_name, lp_workgroup());
88                 fstrcpy(request.data.name.name, name);
89         }
90
91         if (winbindd_request(WINBINDD_LOOKUPNAME, &request, &response)  
92             != NSS_STATUS_SUCCESS) {
93                 PyErr_SetString(winbind_error, "lookup failed");
94                 return NULL;
95         }
96
97         result = PyString_FromString(response.data.sid.sid);
98
99         return result;
100 }
101
102 /* Convert a sid to a name */
103
104 static PyObject *winbind_sid_to_name(PyObject *self, PyObject *args)
105 {
106         struct winbindd_request request;
107         struct winbindd_response response;
108         PyObject *result;
109         char *sid, *name;
110
111         if (!PyArg_ParseTuple(args, "s", &sid))
112                 return NULL;
113
114         ZERO_STRUCT(request);
115         ZERO_STRUCT(response);
116
117         fstrcpy(request.data.sid, sid);
118
119         if (winbindd_request(WINBINDD_LOOKUPSID, &request, &response)  
120             != NSS_STATUS_SUCCESS) {
121                 PyErr_SetString(winbind_error, "lookup failed");
122                 return NULL;
123         }
124
125         /* FIXME: use actual winbind separator */
126
127         asprintf(&name, "%s%c%s", response.data.name.dom_name,
128                  '\\', response.data.name.name);
129
130         result = PyString_FromString(name);
131
132         free(name);
133
134         return result;
135 }
136
137 /*
138  * Method dispatch table
139  */
140
141 static PyMethodDef winbind_methods[] = {
142
143         /* Name <-> SID conversion */
144
145         { "name_to_sid", winbind_name_to_sid, METH_VARARGS,
146           "Convert a name to a sid" },
147
148         { "sid_to_name", winbind_sid_to_name, METH_VARARGS,
149           "Convert a sid to a name" },
150
151         { NULL }
152 };
153
154 /*
155  * Module initialisation 
156  */
157
158 void initwinbind(void)
159 {
160         PyObject *module, *dict;
161
162         /* Initialise module */
163
164         module = Py_InitModule("winbind", winbind_methods);
165         dict = PyModule_GetDict(module);
166
167         winbind_error = PyErr_NewException("winbind.error", NULL, NULL);
168         PyDict_SetItemString(dict, "error", winbind_error);
169 }