mlmmj.mlmmj.org archive mirror
 help / color / mirror / Atom feed
From: Geert Stappers <stappers@stappers.nl>
To: mlmmj@mlmmj.org
Subject: [mlmmj] mlmmj-chown
Date: Sat, 03 Jun 2017 14:23:34 +0000	[thread overview]
Message-ID: <20170603142334.GE32244@gpm.stappers.nl> (raw)

[-- Attachment #1: Type: text/plain, Size: 1002 bytes --]

Summary: making possible that user can do
  chown -R mlmmj $MLMMJ_TOPDIR


Hello,

Those who want and did

  chown -R mlmmj /var/spool/mlmmj/teamfoo

will have seen

  chown: changing ownership of '/var/spool/mlmmj/teamfoo/index': Operation not permitted
  chown: changing ownership of '/var/spool/mlmmj/teamfoo/requeue': Operation not permitted
  chown: changing ownership of '/var/spool/mlmmj/teamfoo/moderation': Operation not permitted
  chown: changing ownership of '/var/spool/mlmmj/teamfoo/mlmmj-maintd.lastrun.log': Operation not permitted

and are tempted to do

  sudo chown -R mlmmj /var/spool/mlmmj/teamfoo

But `sudo` is not allowed for all users and surely not wanted
for webusers  ( the operating system user that runs the webserver process )

And sudo privilege is overkill for only the CAP_CHOWN capability is needed.

However setting CAP_CHOWN on a script has no effect, a binary is neeed.

Find attached the source for such binary.



Groeten
Geert Stappers
-- 
Leven en laten leven

[-- Attachment #2: mlmmj-chown.c --]
[-- Type: text/x-csrc, Size: 2572 bytes --]

/*
 *
 *  mlmmj-chown  /abso/lute/path/to/mlmmj/list
 *
 *  programm for non-root to change ownership to mlmmj user
 *
 *
 *  to build do
 *    gcc -o mlmmj-chown -D MLMMJ_USER=\"mlmmj\" mlmmj-chown.c
 *
 *  you have to do
 *    sudo /sbin/setcap cap_chown+ep ./mlmmj-chown
 *  before using
 *
 *  (C) 2017  Geert Stappers <stappers@stappers.it>
 *  Same license as mlmmj,
 *  it is okay to use this programm outside the mlmmj project
 *
 */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <pwd.h>

#ifndef MLMMJ_USER
#define MLMMJ_USER "mlmmj"
#endif

/* Global variables */
int verbose ;
uid_t uid ;

static void chownR( const char *fname ) ;

int main(int argc, char *argv[])
{
	int opt ;

	struct passwd *pwd;

	verbose = 0 ;

	while ((opt = getopt(argc, argv, "v")) != -1) {
		switch (opt) {
		case 'v':
			verbose = 1;
			break;
		default:
			fprintf(stderr, "Usage: %s [-v] /p/a/t/h\n",
				argv[0]);
			exit(EXIT_FAILURE);
		}
	}
	if (verbose) printf("Verbose flag is set.\n");

	if ( optind >= argc ) {
		fprintf(stderr, "Missing /p/a/t/h\n");
		exit(EXIT_FAILURE);
	}
	if (verbose) printf("Path argument '%s'\n", argv[optind]);

	/* Wish:
	 * tests on valid user input for the path to mlmmj listdir
	 */

	pwd = getpwnam(MLMMJ_USER);
	if (pwd == NULL) {
		fprintf(stderr,
			"No user '%s' in getent passwd.\n", MLMMJ_USER);
		exit(EXIT_FAILURE);
	}
	uid = pwd->pw_uid;
	if (verbose) printf("User ID of '%s' is %d.\n", MLMMJ_USER, uid);

	/* Start change owner */
	if (chown(argv[optind], uid, -1) == -1) {
		perror("chown");
		fprintf(stderr, "for %s\n", argv[optind] );
		exit(EXIT_FAILURE);
	}
	/* and continue recursive */
	chownR(argv[optind]);
	if (verbose) printf("Done.\n");

	exit(EXIT_SUCCESS);
}

void chownR( const char *fname )
{
	DIR *dir;
	struct dirent *entry;

	if (!(dir = opendir(fname)))
		return;
	if (!(entry = readdir(dir)))
		return;
	do {
		char path[1024];
		int len = snprintf(path, sizeof(path)-1,
				"%s/%s", fname, entry->d_name);
		path[len] = 0;
		if (entry->d_type == DT_DIR) {
			if (strcmp(entry->d_name, ".") == 0
					|| strcmp(entry->d_name, "..") == 0)
				continue;
			if (verbose) printf("d %s\n", path);
			if (chown(path, uid, -1) == -1) {
				perror("chown");
				fprintf(stderr, "on directory %s\n", path );
			}
			chownR(path);
		}
		else {
			if (verbose) printf("f %s\n", path);
			if (chown(path, uid, -1) == -1) {
				perror("chown");
				fprintf(stderr, "on file %s\n", path );
			}
		}
	} while (entry = readdir(dir));
	closedir(dir);
}

/* l l */

             reply	other threads:[~2017-06-03 14:23 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-03 14:23 Geert Stappers [this message]
2017-06-03 14:50 ` [mlmmj] mlmmj-chown Marvin Gülker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170603142334.GE32244@gpm.stappers.nl \
    --to=stappers@stappers.nl \
    --cc=mlmmj@mlmmj.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).