]> TLD Linux GIT Repositories - tld-ftp-admin.git/blob - ucred/ucred.c
- raw from PLD
[tld-ftp-admin.git] / ucred / ucred.c
1 #include <Python.h>
2 #include <sys/types.h>
3 #include <sys/socket.h>
4 #include <signal.h>
5
6 PyObject *g_socketerror; // socket.error
7
8 static PyObject *ucred_sendcreds(PyObject *self, PyObject *args, PyObject *keywds);
9 static PyObject *ucred_recvcreds(PyObject *self, PyObject *args, PyObject *keywds);
10
11 static PyMethodDef ucredMethods[] = {
12     {"sendcreds", (PyCFunction)ucred_sendcreds, METH_VARARGS|METH_KEYWORDS, NULL},
13     {"recvcreds", (PyCFunction)ucred_recvcreds, METH_VARARGS|METH_KEYWORDS, NULL},
14     {NULL, NULL, 0, NULL}
15 };
16
17 void initucred(void) {
18     PyObject *module;
19     module = Py_InitModule("ucred", ucredMethods);
20
21         if(-1 == PyModule_AddIntConstant(module, "SO_PASSCRED", SO_PASSCRED)) {
22                 return;
23         }
24
25     module = PyImport_ImportModule("socket");
26     if(!module) {
27         return;
28     }
29     g_socketerror = PyObject_GetAttrString(module, "error");
30     if(!g_socketerror) {
31         return;
32     }
33 }
34
35 static PyObject *ucred_sendcreds(PyObject *self, PyObject *args, PyObject *keywds) {
36     int fd;
37     int ret;
38     int pid=-1, uid=-1, gid=-1;
39     struct msghdr msg;
40     struct iovec iov[1];
41         struct ucred uc;
42         unsigned char control[CMSG_SPACE(sizeof(struct ucred))];
43         struct cmsghdr *cur;
44
45     static char *kwlist[] = {"fd",
46                                                          "pid",
47                                                          "uid",
48                                                          "gid",
49                                                          NULL};
50
51 //    kill(0, SIGTRAP);
52     if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|iii", kwlist, 
53                                 &fd,
54                                 &pid,
55                                 &uid,
56                                 &gid)) {
57         return NULL;
58     }
59 //    kill(0, SIGTRAP);
60
61         if(pid!=-1)
62                 uc.pid=pid;
63         else
64                 uc.pid=getpid();
65         if(uid!=-1)
66                 uc.uid=uid;
67         else
68                 uc.uid=getuid();
69         if(gid!=-1)
70                 uc.gid=gid;
71         else
72                 uc.gid=getgid();
73
74         iov[0].iov_base="SCM_CREDENTIALS";
75         iov[0].iov_len=15;
76
77         memset(&msg, 0, sizeof(msg));
78     msg.msg_iov = iov;
79     msg.msg_iovlen = 1;
80         msg.msg_control = &control;
81         msg.msg_controllen = sizeof(control);
82
83         cur = CMSG_FIRSTHDR(&msg);
84         cur->cmsg_level = SOL_SOCKET;
85         cur->cmsg_type = SCM_CREDENTIALS;
86         cur->cmsg_len = CMSG_SPACE(sizeof(struct ucred));
87         memcpy(CMSG_DATA(cur), &uc, sizeof(struct ucred));
88
89     ret = sendmsg(fd, &msg, 0);
90     if(ret < 0) {
91         PyErr_SetFromErrno(g_socketerror);
92         return NULL;
93     }
94
95     return Py_BuildValue("i", ret);
96 }
97
98 static PyObject *ucred_recvcreds(PyObject *self, PyObject *args, PyObject *keywds) {
99     int fd;
100     int flags=0;
101     size_t maxsize=1024;
102         char control[CMSG_SPACE(sizeof(struct ucred))];
103     int ret;
104         int pid=-1, uid=-1, gid=-1;
105     struct msghdr msg;
106     struct iovec iov[1];
107         struct cmsghdr *cur;
108         struct ucred *uc;
109
110
111     static char *kwlist[] = {"fd", "flags", "maxsize", NULL};
112
113     if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|ii", kwlist,
114             &fd, &flags, &maxsize)) {
115         return NULL;
116     }
117
118         memset(&msg, 0, sizeof(msg));
119
120     iov[0].iov_len = maxsize;
121     iov[0].iov_base = malloc(maxsize);
122     if (!iov[0].iov_base) {
123         PyErr_NoMemory();
124         return NULL;
125     }
126     msg.msg_iov = iov;
127     msg.msg_iovlen = 1;
128
129     msg.msg_control = &control;
130     msg.msg_controllen = sizeof(control);
131
132     ret = recvmsg(fd, &msg, flags);
133     if (ret < 0) {
134         PyErr_SetFromErrno(g_socketerror);
135         free(iov[0].iov_base);
136         return NULL;
137     }
138
139         cur=CMSG_FIRSTHDR(&msg);
140
141         if(cur && cur->cmsg_type==SCM_CREDENTIALS && cur->cmsg_level==SOL_SOCKET)
142         {
143                 assert(cur->cmsg_len >= sizeof(struct cmsghdr));
144                                                 // no null ancillary data messages?
145
146                 uc=(struct ucred*)CMSG_DATA(cur);
147                 pid=uc->pid;
148                 uid=uc->uid;
149                 gid=uc->gid;
150         }
151
152     {
153         PyObject *r;
154         r = Py_BuildValue("s#iii",
155                 iov[0].iov_base, ret,
156                 pid, uid, gid);
157         free(iov[0].iov_base);
158         return r;
159     }
160 }
161
162