PERFORCE change 123175 for review
Alexey Mikhailov
karma at FreeBSD.org
Mon Jul 9 05:49:29 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=123175
Change 123175 by karma at karma_ez on 2007/07/09 05:49:23
* Add search function to T-Tree implementation
* Add remote credentials checking
* write() -> sendmsg() migration in library
Affected files ...
.. //depot/projects/soc2007/karma_audit/dlog/config.h#4 edit
.. //depot/projects/soc2007/karma_audit/dlog/daemon/client.c#3 edit
.. //depot/projects/soc2007/karma_audit/dlog/daemon/config.c#3 edit
.. //depot/projects/soc2007/karma_audit/dlog/daemon/config.h#3 edit
.. //depot/projects/soc2007/karma_audit/dlog/daemon/server.c#3 edit
.. //depot/projects/soc2007/karma_audit/dlog/daemon/ttree.c#2 edit
.. //depot/projects/soc2007/karma_audit/dlog/daemon/ttree.h#2 edit
.. //depot/projects/soc2007/karma_audit/dlog/lib/libdlogd.c#3 edit
.. //depot/projects/soc2007/karma_audit/dlog/lib/libdlogd.h#3 edit
Differences ...
==== //depot/projects/soc2007/karma_audit/dlog/config.h#4 (text+ko) ====
@@ -14,4 +14,6 @@
#define SERVER_PORT "9991"
+#define QLEN 10
+
#endif
==== //depot/projects/soc2007/karma_audit/dlog/daemon/client.c#3 (text+ko) ====
@@ -12,28 +12,96 @@
void
client_main()
{
- int s, opt = 1;
+ int s, cs, opt = 1;
+ size_t nr = 0;
struct sockaddr_un n;
+ char buf[KEYWORD_MAX+PATH_MAX+1];
+ char keyword[KEYWORD_MAX];
+ char pathname[PATH_MAX];
+ struct msghdr msg;
+ struct iovec iov[2];
+ union {
+ struct cmsghdr cm;
+ char control[CMSG_SPACE(sizeof(struct cmsgcred))];
+ } c;
+ struct cmsghdr *cm;
+ union
+ {
+ struct sockcred uc;
+ char b[sizeof (struct sockcred) + NGROUPS * sizeof (int)];
+ } cr;
+
+ cm = &c.cm;
+
+ msg.msg_control = c.control;
+ msg.msg_controllen = sizeof(c.control);
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+
+ bzero(keyword, KEYWORD_MAX);
+ bzero(pathname, PATH_MAX);
+ bzero(buf, KEYWORD_MAX + PATH_MAX + 1);
+
+ iov[0].iov_base = buf;
+ iov[0].iov_len = PATH_MAX + KEYWORD_MAX + 1;
+
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+
s = socket(PF_LOCAL, SOCK_STREAM, 0);
- if (s < 0)
- {
+ if (s < 0) {
err_fatal("can't create PF_LOCAL socket");
}
-
- if ((setsockopt(s, 0, LOCAL_CREDS, &opt, sizeof(opt))) < 0)
- {
+
+ unlink(DL_SOCKET);
+
+ if ((setsockopt(s, 0, LOCAL_CREDS, &opt, sizeof(opt))) < 0) {
err_fatal("can't receive credentials from PF_LOCAL socket");
}
-
+
bzero(&n, sizeof(n));
n.sun_family = PF_LOCAL;
- strncpy(n.sun_path, DL_SOCKET, sizeof(DL_SOCKET));
+ strcpy(n.sun_path, DL_SOCKET);
+
+ if ((bind(s, (struct sockaddr *) &n, SUN_LEN (&n))) < 0) {
+ err_fatal("can't bind PF_LOCAL socket. Another instance is running?");
+ }
+
+ if (listen(s, QLEN) < 0) {
+ err_fatal("cat't listen() on PF_LOCAL socket.");
+ }
- if ((bind(s, (struct sockaddr *) &n, SUN_LEN (&n))) < 0)
- {
- err_fatal("can't bind PF_LOCAL socket");
+ while ((cs = accept(s, (struct sockaddr *) NULL, NULL)) >= 0) {
+
+ nr = recvmsg (cs, &msg, 0);
+
+ /* TODO: could go bad here.. fix later.. */
+ if ((sscanf(buf, "%s\n%s", pathname, keyword)) < 2) {
+ printf("ouch!");
+ /* TODO: wrong query */
+ }
+
+#ifdef DEBUG
+ printf("RECEIVED: %s %s\n", pathname, keyword);
+#endif
+
+ if (cm -> cmsg_type == SCM_CREDS) {
+ memcpy(&cr, ((struct sockcred *) CMSG_DATA(cm)),
+ cm -> cmsg_len - sizeof(struct cmsghdr));
+#ifdef DEBUG
+ printf("UID %d, GID %d\n", cr.uc.sc_uid, cr.uc.sc_gid);
+#endif
+ if ((verify_client_access(cr.uc.sc_uid, cr.uc.sc_gid)) == 0)
+ {
+ /* TODO: add logfile to spool here */
+ }
+
+ } else {
+ /* TODO: can't check permissions. wrong query */
+ printf("can't check permissions");
+ }
+ close(cs);
}
-
}
==== //depot/projects/soc2007/karma_audit/dlog/daemon/config.c#3 (text+ko) ====
@@ -104,13 +104,13 @@
if (strcmp(id, "uid") == 0)
{
pcka -> id = 1;
- pcka -> ut = (uid_t)strtol(val, (char **)NULL, 10);
- if (pcka -> ut == 0)
+ pcka -> uid = (uid_t)strtol(val, (char **)NULL, 10);
+ if (pcka -> uid == 0)
{
err_fatal("wrong UID.");
}
- struct passwd * psw = getpwuid(pcka -> ut);
+ struct passwd * psw = getpwuid(pcka -> uid);
if (psw == NULL)
{
@@ -122,13 +122,13 @@
if (strcmp(id, "gid") == 0)
{
pcka -> id = 2;
- pcka -> gt = (gid_t)strtol(val, (char **)NULL, 10);
- if (pcka -> gt == 0)
+ pcka -> gid = (gid_t)strtol(val, (char **)NULL, 10);
+ if (pcka -> gid == 0)
{
err_fatal("wrong gid");
}
- struct group * grp = getgrgid (pcka -> gt);
+ struct group * grp = getgrgid (pcka -> gid);
if (grp = NULL)
{
@@ -148,7 +148,7 @@
err_fatal("getpwnam() failed. Probably wrong username.");
}
- pcka -> ut = psw -> pw_uid;
+ pcka -> uid = psw -> pw_uid;
return 0;
}
@@ -161,7 +161,7 @@
err_fatal("getgrnam() failed. Probably wrong groupname.");
}
- pcka -> gt = grp -> gr_gid;
+ pcka -> gid = grp -> gr_gid;
return 0;
}
@@ -245,3 +245,48 @@
{
return 0;
}
+
+/* Verify client access (with specified uid and gid) to specified keyword
+
+ If success: 0 returned
+ If failed: -1, bad keyword
+ -2, access denied
+*/
+
+int
+verify_client_access (const char * keyword, uid_t uid, gid_t gid)
+{
+ cl_kw_data * ck;
+ cl_kw_access * ca;
+
+ ck = (cl_kw_data *)search_tree(client_kw_tree, keyword);
+
+ if (ck == NULL)
+ {
+ return (-1); /* bad keyword */
+ }
+
+ ca = ck -> access;
+
+ while (ca != NULL)
+ {
+ if (ca -> id == 1)
+ {
+ if (uid == ca -> uid)
+ {
+ return 0;
+ }
+ }
+ if (ca -> id == 2)
+ {
+ if (gid == ca -> gid)
+ {
+ return 0;
+ }
+ }
+ }
+
+ /* TODO: check for supplementary groups for UID as well */
+
+ return (-2); /* access denied */
+}
==== //depot/projects/soc2007/karma_audit/dlog/daemon/config.h#3 (text+ko) ====
@@ -5,8 +5,8 @@
typedef struct client_kw_access {
int id;
- uid_t ut;
- gid_t gt;
+ uid_t uid;
+ gid_t gid;
struct client_kw_access * next;
} cl_kw_access;
@@ -46,4 +46,6 @@
void parse_client_config();
void parse_server_config();
+int verify_client_access (const char * keyword, uid_t uid, gid_t gid);
+
#endif
==== //depot/projects/soc2007/karma_audit/dlog/daemon/server.c#3 (text+ko) ====
@@ -4,8 +4,6 @@
#include <stdio.h>
#include <sys/socket.h>
-#define QLEN 10
-
void
server_serve (int s)
{
==== //depot/projects/soc2007/karma_audit/dlog/daemon/ttree.c#2 (text+ko) ====
@@ -12,6 +12,7 @@
#define MAX(x,y) ((x > y) ? x : y)
#define LT(x, y) ((strcmp(x,y)) < (0))
#define GT(x, y) ((strcmp(x,y)) > (0))
+#define EQ(x, y) ((strcmp(x,y)) == (0))
#if 0
inline void
@@ -336,3 +337,49 @@
}
}
+/* Search tree for key.
+
+ If success: pointer to value is returned.
+ If failed: NULL returned
+*/
+
+void *
+search_tree (TTree * d, const char * key)
+{
+ TData *tn;
+
+ if (d -> l == NULL)
+ return NULL;
+
+ if (LT(key, d -> l -> key))
+ {
+ if (d -> tl == NULL)
+ return NULL;
+ else
+ return (search_tree(d -> tl, key));
+ }
+
+ if (GT(key, d -> r -> key))
+ {
+ if (d -> tr == NULL)
+ return NULL;
+ else
+ return (search_tree(d -> tr, key));
+ }
+
+ tn = d -> l;
+
+ while (tn != NULL)
+ {
+ if (EQ(key, tn->key))
+ {
+ return tn -> content;
+ }
+ else
+ {
+ tn = tn -> next;
+ }
+ }
+
+ return NULL;
+}
==== //depot/projects/soc2007/karma_audit/dlog/daemon/ttree.h#2 (text+ko) ====
@@ -22,6 +22,6 @@
TTree * allocate_ttree();
int insert_tree (TTree **, char *, void *);
-void traverse_tree (TTree *,int);
+void * search_tree (TTree *, const char * key);
#endif
==== //depot/projects/soc2007/karma_audit/dlog/lib/libdlogd.c#3 (text+ko) ====
@@ -5,18 +5,15 @@
#include <stddef.h>
#include <errno.h>
#include <unistd.h>
+#include <sys/param.h>
#include <sys/poll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/syslimits.h>
#include <sys/un.h>
-
-#define BUF_SIZE PATH_MAX+KEYWORD_MAX+2
-
-static int timeout = 1000;
+#include <sys/ucred.h>
-static int dlogd_send (int fd, const char * buf, size_t len);
static int dlogd_connect ();
/* Submit log file
@@ -29,7 +26,14 @@
{
int fd, rc;
size_t len;
- char buf[BUF_SIZE];
+ char buf[KEYWORD_MAX + PATH_MAX + 1];
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ struct iovec iov[1];
+ union {
+ struct cmsghdr cm;
+ char control[CMSG_SPACE(sizeof(struct cmsgcred))];
+ } c;
if (strlen(pathname) > PATH_MAX)
{
@@ -45,69 +49,42 @@
return fd;
}
- snprintf(buf, BUF_SIZE, "%s\n%s\n", keyword, pathname);
- len = strlen(buf);
+ snprintf(buf, strlen(pathname)+strlen(keyword)+2, "%s\n%s", pathname, keyword);
+
+ /* Construct message */
- rc = dlogd_send(fd, buf, len);
+ iov[0].iov_base = buf;
+ iov[0].iov_len = strlen(pathname)+strlen(keyword)+2;
- if (rc < 0)
- return rc;
+ bzero(&msg, sizeof(msg));
+ msg.msg_control = c.control;
+ msg.msg_controllen = sizeof(c.control);
- /* TODO: write dlogd_receive and wait for server's reply */
-
- return 0;
-}
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg -> cmsg_len = CMSG_LEN(sizeof(struct cmsgcred));
+ cmsg -> cmsg_level = SOL_SOCKET;
+ cmsg -> cmsg_type = SCM_CREDS;
-/* Send buf through fd descriptor
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
- On success: 0 returned
-
- On failure: -1 returned
-*/
-
-static int
-dlogd_send (int fd, const char * buf, size_t len)
-{
- struct pollfd fds;
- int rc, bytes;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
- fds.fd = fd;
- fds.events = POLLOUT;
+ if (sendmsg (fd, &msg, 0) < 0)
+ {
+ close(fd);
+ return (-5); /* can't sendmsg */
+ }
- while (len)
- {
- fds.revents = 0;
- rc = poll(&fds, 1, timeout * 1000);
- if (rc == 0)
- return (-1); /* timeout */
- else if (rc < 0)
- {
- if (errno == EINTR || errno == EAGAIN)
- continue;
- else
- return (-1);
- }
-
- if (!fds.revents)
- return (-1);
-
- bytes = write(fd,buf,len);
-
- if (bytes < 0)
- {
- if (errno == EINTR)
- continue;
- else
- return (-1);
- }
+ rc = close(fd);
- len -= bytes;
- buf += bytes;
- }
+ printf("close returned %d\n", rc);
return 0;
}
+
/* Connect to local daemon through PF_LOCAL socket.
On success: descriptor returned
==== //depot/projects/soc2007/karma_audit/dlog/lib/libdlogd.h#3 (text+ko) ====
More information about the p4-projects
mailing list