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 module = PyImport_ImportModule("socket");
25 g_socketerror = PyObject_GetAttrString(module, "error");
31 static PyObject *ucred_sendcreds(PyObject *self, PyObject *args, PyObject *keywds) {
34 int pid=-1, uid=-1, gid=-1;
38 unsigned char control[CMSG_SPACE(sizeof(struct ucred))];
41 static char *kwlist[] = {"fd",
48 if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|iii", kwlist,
70 iov[0].iov_base="SCM_CREDENTIALS";
73 memset(&msg, 0, sizeof(msg));
76 msg.msg_control = &control;
77 msg.msg_controllen = sizeof(control);
79 cur = CMSG_FIRSTHDR(&msg);
80 cur->cmsg_level = SOL_SOCKET;
81 cur->cmsg_type = SCM_CREDENTIALS;
82 cur->cmsg_len = CMSG_SPACE(sizeof(struct ucred));
83 memcpy(CMSG_DATA(cur), &uc, sizeof(struct ucred));
85 ret = sendmsg(fd, &msg, 0);
87 PyErr_SetFromErrno(g_socketerror);
91 return Py_BuildValue("i", ret);
94 static PyObject *ucred_recvcreds(PyObject *self, PyObject *args, PyObject *keywds) {
98 char control[CMSG_SPACE(sizeof(struct ucred))];
100 int pid=-1, uid=-1, gid=-1;
107 static char *kwlist[] = {"fd", "flags", "maxsize", NULL};
109 if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|ii", kwlist,
110 &fd, &flags, &maxsize)) {
114 memset(&msg, 0, sizeof(msg));
116 iov[0].iov_len = maxsize;
117 iov[0].iov_base = malloc(maxsize);
118 if (!iov[0].iov_base) {
125 msg.msg_control = &control;
126 msg.msg_controllen = sizeof(control);
128 ret = recvmsg(fd, &msg, flags);
130 PyErr_SetFromErrno(g_socketerror);
131 free(iov[0].iov_base);
135 cur=CMSG_FIRSTHDR(&msg);
137 if(cur && cur->cmsg_type==SCM_CREDENTIALS && cur->cmsg_level==SOL_SOCKET)
139 assert(cur->cmsg_len >= sizeof(struct cmsghdr));
140 // no null ancillary data messages?
142 uc=(struct ucred*)CMSG_DATA(cur);
150 r = Py_BuildValue("s#iii",
151 iov[0].iov_base, ret,
153 free(iov[0].iov_base);