svn commit: samba r25837 - in branches/SAMBA_4_0/source/lib/nss_wrapper: .

metze at samba.org metze at samba.org
Mon Nov 5 15:42:38 GMT 2007


Author: metze
Date: 2007-11-05 15:42:38 +0000 (Mon, 05 Nov 2007)
New Revision: 25837

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=25837

Log:
nss_wrapper: add nss_wrapper.pl

This script will be used to add|delete passwd|group entries

metze
Added:
   branches/SAMBA_4_0/source/lib/nss_wrapper/nss_wrapper.pl


Changeset:
Added: branches/SAMBA_4_0/source/lib/nss_wrapper/nss_wrapper.pl
===================================================================
--- branches/SAMBA_4_0/source/lib/nss_wrapper/nss_wrapper.pl	2007-11-05 15:41:23 UTC (rev 25836)
+++ branches/SAMBA_4_0/source/lib/nss_wrapper/nss_wrapper.pl	2007-11-05 15:42:38 UTC (rev 25837)
@@ -0,0 +1,265 @@
+#!/usr/bin/perl
+#
+
+use strict;
+
+use Getopt::Long;
+use Cwd qw(abs_path);
+
+my $opt_help = 0;
+my $opt_path = undef;
+my $opt_action = undef;
+my $opt_type = undef;
+my $opt_name = undef;
+
+my $passwdfn = undef;
+my $groupfn = undef;
+my $actionfn = undef;
+
+sub passwd_add($$);
+sub passwd_delete($$);
+sub group_add($$);
+sub group_delete($$);
+
+my $result = GetOptions(
+	'help|h|?'	=> \$opt_help,
+	'path=s'	=> \$opt_path,
+	'action=s'	=> \$opt_action,
+	'type=s'	=> \$opt_type,
+	'name=s'	=> \$opt_name
+);
+
+sub usage($;$)
+{
+	my ($ret, $msg) = @_;
+
+	print $msg."\n\n" if defined($msg);
+
+	print "usage:
+
+	--help|-h|-?		Show this help.
+
+	--path <path>		Path of the 'passwd' or 'group' file.
+
+	--type <type>		Only 'passwd' is supported yet,
+				but 'group' and maybe 'member' will be added
+				in future.
+
+	--action <action>	'add' or 'delete'.
+
+	--name <name>		The name of the object.
+";
+	exit($ret);
+}
+
+usage(1) if (not $result);
+
+usage(0) if ($opt_help);
+
+if (not defined($opt_path)) {
+	usage(1, "missing: --path <path>");
+}
+if ($opt_path eq "" or $opt_path eq "/") {
+	usage(1, "invalid: --path <path>: '$opt_path'");
+}
+my $opt_fullpath = abs_path($opt_path);
+if (not defined($opt_fullpath)) {
+	usage(1, "invalid: --path <path>: '$opt_path'");
+}
+
+
+if (not defined($opt_action)) {
+	usage(1, "missing: --action [add|delete]");
+}
+if ($opt_action eq "add") {
+	$passwdfn = \&passwd_add;
+	$groupfn = \&group_add;
+} elsif ($opt_action eq "delete") {
+	$passwdfn = \&passwd_delete;
+	$groupfn = \&group_delete;
+} else {
+	usage(1, "invalid: --action [add|delete]: '$opt_action'");
+}
+
+if (not defined($opt_type)) {
+	usage(1, "missing: --type [passwd|group]");
+}
+if ($opt_type eq "passwd") {
+	$actionfn = $passwdfn;
+} elsif ($opt_type eq "group") {
+	$actionfn = $groupfn;
+} else {
+	usage(1, "invalid: --type [passwd|group]: '$opt_type'")
+}
+
+if (not defined($opt_name)) {
+	usage(1, "missing: --name <name>");
+}
+if ($opt_name eq "") {
+	usage(1, "invalid: --name <name>");
+}
+
+exit $actionfn->($opt_fullpath, $opt_name);
+
+sub passwd_add_entry($$);
+
+sub passwd_load($)
+{
+	my ($path) = @_;
+	my @lines;
+	my $passwd = undef;
+
+	open(PWD, "<$path") or die("Unable to open '$path' for read");
+	@lines = <PWD>;
+	close(PWD);
+
+	$passwd->{array} = ();
+	$passwd->{name} = {};
+	$passwd->{uid} = {};
+	$passwd->{path} = $path;
+
+	foreach my $line (@lines) {
+		passwd_add_entry($passwd, $line);
+	}
+
+	return $passwd;
+}
+
+sub passwd_lookup_name($$)
+{
+	my ($passwd, $name) = @_;
+
+	return undef unless defined($passwd->{name}{$name});
+
+	return $passwd->{name}{$name};
+}
+
+sub passwd_lookup_uid($$)
+{
+	my ($passwd, $uid) = @_;
+
+	return undef unless defined($passwd->{uid}{$uid});
+
+	return $passwd->{uid}{$uid};
+}
+
+sub passwd_get_free_uid($)
+{
+	my ($passwd) = @_;
+	my $uid = 1000;
+
+	while (passwd_lookup_uid($passwd, $uid)) {
+		$uid++;
+	}
+
+	return $uid;
+}
+
+sub passwd_add_entry($$)
+{
+	my ($passwd, $str) = @_;
+
+	chomp $str;
+	my @e = split(':', $str);
+
+	push(@{$passwd->{array}}, \@e);
+	$passwd->{name}{$e[0]} = \@e;
+	$passwd->{uid}{$e[2]} = \@e;
+}
+
+sub passwd_remove_entry($$)
+{
+	my ($passwd, $eref) = @_;
+
+	for(my $i; defined($passwd->{array}[$i]); $i++) {
+		if ($eref == $passwd->{array}[$i]) {
+			$passwd->{array}[$i] = undef;
+		}
+	}
+
+	delete $passwd->{name}{${$eref}[0]};
+	delete $passwd->{uid}{${$eref}[2]};
+}
+
+sub passwd_save($)
+{
+	my ($passwd) = @_;
+	my @lines = ();
+	my $path = $passwd->{path};
+	my $tmppath = $path.$$;
+
+	foreach my $eref (@{$passwd->{array}}) {
+		next unless defined($eref);
+
+		my $line = join(':', @{$eref});
+		push(@lines, $line);
+	}
+
+	open(PWD, ">$tmppath") or die("Unable to open '$tmppath' for write");
+	print PWD join("\n", @lines)."\n";
+	close(PWD);
+	rename($tmppath, $path) or die("Unable to rename $tmppath => $path");
+}
+
+sub passwd_add($$)
+{
+	my ($path, $name) = @_;
+
+	#print "passwd_add: '$name' in '$path'\n";
+
+	my $passwd = passwd_load($path);
+
+	my $e = passwd_lookup_name($passwd, $name);
+	die("account[$name] already exists in '$path'") if defined($e);
+
+	my $uid = passwd_get_free_uid($passwd);
+	my $gid = 65534;# nogroup gid
+
+	my $pwent = $name.":x:".$uid.":".$gid.":".$name." gecos:/nodir:/bin/false";
+
+	passwd_add_entry($passwd, $pwent);
+
+	passwd_save($passwd);
+
+	return 0;
+}
+
+sub passwd_delete($$)
+{
+	my ($path, $name) = @_;
+
+	#print "passwd_delete: '$name' in '$path'\n";
+
+	my $passwd = passwd_load($path);
+
+	my $e = passwd_lookup_name($passwd, $name);
+	die("account[$name] does not exists in '$path'") unless defined($e);
+
+	passwd_remove_entry($passwd, $e);
+
+	passwd_save($passwd);
+
+	return 0;
+}
+
+sub group_add($$)
+{
+	my ($path, $name) = @_;
+
+	#print "group_add: '$name' in '$path'\n";
+
+	die("group_add: not implemented yet!");
+
+	return 0;
+}
+
+sub group_delete($$)
+{
+	my ($path, $name) = @_;
+
+	#print "group_delete: '$name' in '$path'\n";
+
+	die("group_delete: not implemented yet!");
+
+	return 0;
+}



More information about the samba-cvs mailing list