From owner-p4-projects@FreeBSD.ORG Mon Jul 9 05:49:28 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 9B17416A46B; Mon, 9 Jul 2007 05:49:28 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 6CED216A421 for ; Mon, 9 Jul 2007 05:49:28 +0000 (UTC) (envelope-from karma@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 5C28613C4B0 for ; Mon, 9 Jul 2007 05:49:28 +0000 (UTC) (envelope-from karma@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l695nSMf049666 for ; Mon, 9 Jul 2007 05:49:28 GMT (envelope-from karma@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l695nS43049639 for perforce@freebsd.org; Mon, 9 Jul 2007 05:49:28 GMT (envelope-from karma@FreeBSD.org) Date: Mon, 9 Jul 2007 05:49:28 GMT Message-Id: <200707090549.l695nS43049639@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to karma@FreeBSD.org using -f From: Alexey Mikhailov To: Perforce Change Reviews Cc: Subject: PERFORCE change 123175 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Jul 2007 05:49:29 -0000 http://perforce.freebsd.org/chv.cgi?CH=123175 Change 123175 by karma@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 #include -#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 #include #include +#include #include #include #include #include #include #include - -#define BUF_SIZE PATH_MAX+KEYWORD_MAX+2 - -static int timeout = 1000; +#include -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) ====