3 #include <sys/socket.h>
6 PyObject *g_socketerror; // socket.error
8 static PyObject *ucred_sendcreds(PyObject *self, PyObject *args, PyObject *keywds);
9 static PyObject *ucred_recvcreds(PyObject *self, PyObject *args, PyObject *keywds);
11 static PyMethodDef ucredMethods[] = {
12 {"sendcreds", (PyCFunction)ucred_sendcreds, METH_VARARGS|METH_KEYWORDS, NULL},
13 {"recvcreds", (PyCFunction)ucred_recvcreds, METH_VARARGS|METH_KEYWORDS, NULL},
17 void initucred(void) {
19 module = Py_InitModule("ucred", ucredMethods);
21 if(-1 == PyModule_AddIntConstant(module, "SO_PASSCRED", SO_PASSCRED)) {
25 module = PyImport_ImportModule("socket");
29 g_socketerror = PyObject_GetAttrString(module, "error");
35 static PyObject *ucred_sendcreds(PyObject *self, PyObject *args, PyObject *keywds) {
38 int pid=-1, uid=-1, gid=-1;
42 unsigned char control[CMSG_SPACE(sizeof(struct ucred))];
45 static char *kwlist[] = {"fd",
52 if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|iii", kwlist,
74 iov[0].iov_base="SCM_CREDENTIALS";
77 memset(&msg, 0, sizeof(msg));
80 msg.msg_control = &control;
81 msg.msg_controllen = sizeof(control);
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));
89 ret = sendmsg(fd, &msg, 0);
91 PyErr_SetFromErrno(g_socketerror);
95 return Py_BuildValue("i", ret);
98 static PyObject *ucred_recvcreds(PyObject *self, PyObject *args, PyObject *keywds) {
102 char control[CMSG_SPACE(sizeof(struct ucred))];
104 int pid=-1, uid=-1, gid=-1;
111 static char *kwlist[] = {"fd", "flags", "maxsize", NULL};
113 if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|ii", kwlist,
114 &fd, &flags, &maxsize)) {
118 memset(&msg, 0, sizeof(msg));
120 iov[0].iov_len = maxsize;
121 iov[0].iov_base = malloc(maxsize);
122 if (!iov[0].iov_base) {
129 msg.msg_control = &control;
130 msg.msg_controllen = sizeof(control);
132 ret = recvmsg(fd, &msg, flags);
134 PyErr_SetFromErrno(g_socketerror);
135 free(iov[0].iov_base);
139 cur=CMSG_FIRSTHDR(&msg);
141 if(cur && cur->cmsg_type==SCM_CREDENTIALS && cur->cmsg_level==SOL_SOCKET)
143 assert(cur->cmsg_len >= sizeof(struct cmsghdr));
144 // no null ancillary data messages?
146 uc=(struct ucred*)CMSG_DATA(cur);
154 r = Py_BuildValue("s#iii",
155 iov[0].iov_base, ret,
157 free(iov[0].iov_base);