]> git.pld-linux.org Git - projects/pld-ftp-admin.git/blob - ucred/ucred.c
- sendcreds by default sends current ?ids, but any ?id can be overwritten
[projects/pld-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     module = PyImport_ImportModule("socket");
22     if(!module) {
23         return;
24     }
25     g_socketerror = PyObject_GetAttrString(module, "error");
26     if(!g_socketerror) {
27         return;
28     }
29 }
30
31 static PyObject *ucred_sendcreds(PyObject *self, PyObject *args, PyObject *keywds) {
32     int fd;
33     int ret;
34     int pid=-1, uid=-1, gid=-1;
35     struct msghdr msg;
36     struct iovec iov[1];
37         struct ucred uc;
38         unsigned char control[CMSG_SPACE(sizeof(struct ucred))];
39         struct cmsghdr *cur;
40
41     static char *kwlist[] = {"fd",
42                                                          "pid",
43                                                          "uid",
44                                                          "gid",
45                                                          NULL};
46
47 //    kill(0, SIGTRAP);
48     if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|iii", kwlist, 
49                                 &fd,
50                                 &pid,
51                                 &uid,
52                                 &gid)) {
53         return NULL;
54     }
55 //    kill(0, SIGTRAP);
56
57         if(pid!=-1)
58                 uc.pid=pid;
59         else
60                 uc.pid=getpid();
61         if(uid!=-1)
62                 uc.uid=uid;
63         else
64                 uc.uid=getuid();
65         if(gid!=-1)
66                 uc.gid=gid;
67         else
68                 uc.gid=getgid();
69
70         iov[0].iov_base="SCM_CREDENTIALS";
71         iov[0].iov_len=15;
72
73         memset(&msg, 0, sizeof(msg));
74     msg.msg_iov = iov;
75     msg.msg_iovlen = 1;
76         msg.msg_control = &control;
77         msg.msg_controllen = sizeof(control);
78
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));
84
85     ret = sendmsg(fd, &msg, 0);
86     if(ret < 0) {
87         PyErr_SetFromErrno(g_socketerror);
88         return NULL;
89     }
90
91     return Py_BuildValue("i", ret);
92 }
93
94 static PyObject *ucred_recvcreds(PyObject *self, PyObject *args, PyObject *keywds) {
95     int fd;
96     int flags=0;
97     size_t maxsize=1024;
98         char control[CMSG_SPACE(sizeof(struct ucred))];
99     int ret;
100         int pid=-1, uid=-1, gid=-1;
101     struct msghdr msg;
102     struct iovec iov[1];
103         struct cmsghdr *cur;
104         struct ucred *uc;
105
106
107     static char *kwlist[] = {"fd", "flags", "maxsize", NULL};
108
109     if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|ii", kwlist,
110             &fd, &flags, &maxsize)) {
111         return NULL;
112     }
113
114         memset(&msg, 0, sizeof(msg));
115
116     iov[0].iov_len = maxsize;
117     iov[0].iov_base = malloc(maxsize);
118     if (!iov[0].iov_base) {
119         PyErr_NoMemory();
120         return NULL;
121     }
122     msg.msg_iov = iov;
123     msg.msg_iovlen = 1;
124
125     msg.msg_control = &control;
126     msg.msg_controllen = sizeof(control);
127
128     ret = recvmsg(fd, &msg, flags);
129     if (ret < 0) {
130         PyErr_SetFromErrno(g_socketerror);
131         free(iov[0].iov_base);
132         return NULL;
133     }
134
135         cur=CMSG_FIRSTHDR(&msg);
136
137         if(cur && cur->cmsg_type==SCM_CREDENTIALS && cur->cmsg_level==SOL_SOCKET)
138         {
139                 assert(cur->cmsg_len >= sizeof(struct cmsghdr));
140                                                 // no null ancillary data messages?
141
142                 uc=(struct ucred*)CMSG_DATA(cur);
143                 pid=uc->pid;
144                 uid=uc->uid;
145                 gid=uc->gid;
146         }
147
148     {
149         PyObject *r;
150         r = Py_BuildValue("s#iii",
151                 iov[0].iov_base, ret,
152                 pid, uid, gid);
153         free(iov[0].iov_base);
154         return r;
155     }
156 }
157
158
This page took 0.043066 seconds and 4 git commands to generate.