summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/smtpd/util.c')
-rw-r--r--usr.sbin/smtpd/util.c67
1 files changed, 66 insertions, 1 deletions
diff --git a/usr.sbin/smtpd/util.c b/usr.sbin/smtpd/util.c
index a627e5ae89d..e11307142dd 100644
--- a/usr.sbin/smtpd/util.c
+++ b/usr.sbin/smtpd/util.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.49 2011/10/27 14:32:57 chl Exp $ */
+/* $OpenBSD: util.c,v 1.50 2011/11/14 11:53:10 eric Exp $ */
/*
* Copyright (c) 2000,2001 Markus Friedl. All rights reserved.
@@ -66,6 +66,71 @@ bsnprintf(char *str, size_t size, const char *format, ...)
return 1;
}
+int
+ckdir(const char *path, mode_t mode, uid_t owner, gid_t group, int create)
+{
+ char mode_str[12];
+ int ret;
+ struct stat sb;
+
+ if (stat(path, &sb) == -1) {
+ if (errno != ENOENT || create == 0) {
+ warn("stat: %s", path);
+ return (0);
+ }
+
+ /* chmod is deferred to avoid umask effect */
+ if (mkdir(path, 0) == -1) {
+ warn("mkdir: %s", path);
+ return (0);
+ }
+
+ if (chown(path, owner, group) == -1) {
+ warn("chown: %s", path);
+ return (0);
+ }
+
+ if (chmod(path, mode) == -1) {
+ warn("chmod: %s", path);
+ return (0);
+ }
+
+ if (stat(path, &sb) == -1) {
+ warn("stat: %s", path);
+ return (0);
+ }
+ }
+
+ ret = 1;
+
+ /* check if it's a directory */
+ if (!S_ISDIR(sb.st_mode)) {
+ ret = 0;
+ warnx("%s is not a directory", path);
+ }
+
+ /* check that it is owned by owner/group */
+ if (sb.st_uid != owner) {
+ ret = 0;
+ warnx("%s is not owned by uid %d", path, owner);
+ }
+ if (sb.st_gid != group) {
+ ret = 0;
+ warnx("%s is not owned by gid %d", path, group);
+ }
+
+ /* check permission */
+ if ((sb.st_mode & 07777) != mode) {
+ ret = 0;
+ strmode(mode, mode_str);
+ mode_str[10] = '\0';
+ warnx("%s must be %s (%o)", path, mode_str + 1, mode);
+ }
+
+ return ret;
+}
+
+
/* Close file, signifying temporary error condition (if any) to the caller. */
int
safe_fclose(FILE *fp)