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