Fixed segfault in extended make_connection()
[Samba/vfs_proxy.git] / lib / nss_wrapper / nss_wrapper.pl
blobb1c9be5365bc37234a782c2794d6d98119ed055f
1 #!/usr/bin/perl
4 use strict;
6 use Getopt::Long;
7 use Cwd qw(abs_path);
9 my $opt_help = 0;
10 my $opt_path = undef;
11 my $opt_action = undef;
12 my $opt_type = undef;
13 my $opt_name = undef;
15 my $passwdfn = undef;
16 my $groupfn = undef;
17 my $actionfn = undef;
19 sub passwd_add($$);
20 sub passwd_delete($$);
21 sub group_add($$);
22 sub group_delete($$);
24 my $result = GetOptions(
25 'help|h|?' => \$opt_help,
26 'path=s' => \$opt_path,
27 'action=s' => \$opt_action,
28 'type=s' => \$opt_type,
29 'name=s' => \$opt_name
32 sub usage($;$)
34 my ($ret, $msg) = @_;
36 print $msg."\n\n" if defined($msg);
38 print "usage:
40 --help|-h|-? Show this help.
42 --path <path> Path of the 'passwd' or 'group' file.
44 --type <type> Only 'passwd' is supported yet,
45 but 'group' and maybe 'member' will be added
46 in future.
48 --action <action> 'add' or 'delete'.
50 --name <name> The name of the object.
52 exit($ret);
55 usage(1) if (not $result);
57 usage(0) if ($opt_help);
59 if (not defined($opt_path)) {
60 usage(1, "missing: --path <path>");
62 if ($opt_path eq "" or $opt_path eq "/") {
63 usage(1, "invalid: --path <path>: '$opt_path'");
65 my $opt_fullpath = abs_path($opt_path);
66 if (not defined($opt_fullpath)) {
67 usage(1, "invalid: --path <path>: '$opt_path'");
71 if (not defined($opt_action)) {
72 usage(1, "missing: --action [add|delete]");
74 if ($opt_action eq "add") {
75 $passwdfn = \&passwd_add;
76 $groupfn = \&group_add;
77 } elsif ($opt_action eq "delete") {
78 $passwdfn = \&passwd_delete;
79 $groupfn = \&group_delete;
80 } else {
81 usage(1, "invalid: --action [add|delete]: '$opt_action'");
84 if (not defined($opt_type)) {
85 usage(1, "missing: --type [passwd|group]");
87 if ($opt_type eq "passwd") {
88 $actionfn = $passwdfn;
89 } elsif ($opt_type eq "group") {
90 $actionfn = $groupfn;
91 } else {
92 usage(1, "invalid: --type [passwd|group]: '$opt_type'")
95 if (not defined($opt_name)) {
96 usage(1, "missing: --name <name>");
98 if ($opt_name eq "") {
99 usage(1, "invalid: --name <name>");
102 exit $actionfn->($opt_fullpath, $opt_name);
104 sub passwd_add_entry($$);
106 sub passwd_load($)
108 my ($path) = @_;
109 my @lines;
110 my $passwd = undef;
112 open(PWD, "<$path") or die("Unable to open '$path' for read");
113 @lines = <PWD>;
114 close(PWD);
116 $passwd->{array} = ();
117 $passwd->{name} = {};
118 $passwd->{uid} = {};
119 $passwd->{path} = $path;
121 foreach my $line (@lines) {
122 passwd_add_entry($passwd, $line);
125 return $passwd;
128 sub passwd_lookup_name($$)
130 my ($passwd, $name) = @_;
132 return undef unless defined($passwd->{name}{$name});
134 return $passwd->{name}{$name};
137 sub passwd_lookup_uid($$)
139 my ($passwd, $uid) = @_;
141 return undef unless defined($passwd->{uid}{$uid});
143 return $passwd->{uid}{$uid};
146 sub passwd_get_free_uid($)
148 my ($passwd) = @_;
149 my $uid = 1000;
151 while (passwd_lookup_uid($passwd, $uid)) {
152 $uid++;
155 return $uid;
158 sub passwd_add_entry($$)
160 my ($passwd, $str) = @_;
162 chomp $str;
163 my @e = split(':', $str);
165 push(@{$passwd->{array}}, \@e);
166 $passwd->{name}{$e[0]} = \@e;
167 $passwd->{uid}{$e[2]} = \@e;
170 sub passwd_remove_entry($$)
172 my ($passwd, $eref) = @_;
174 for(my $i; defined($passwd->{array}[$i]); $i++) {
175 if ($eref == $passwd->{array}[$i]) {
176 $passwd->{array}[$i] = undef;
180 delete $passwd->{name}{${$eref}[0]};
181 delete $passwd->{uid}{${$eref}[2]};
184 sub passwd_save($)
186 my ($passwd) = @_;
187 my @lines = ();
188 my $path = $passwd->{path};
189 my $tmppath = $path.$$;
191 foreach my $eref (@{$passwd->{array}}) {
192 next unless defined($eref);
194 my $line = join(':', @{$eref});
195 push(@lines, $line);
198 open(PWD, ">$tmppath") or die("Unable to open '$tmppath' for write");
199 print PWD join("\n", @lines)."\n";
200 close(PWD);
201 rename($tmppath, $path) or die("Unable to rename $tmppath => $path");
204 sub passwd_add($$)
206 my ($path, $name) = @_;
208 #print "passwd_add: '$name' in '$path'\n";
210 my $passwd = passwd_load($path);
212 my $e = passwd_lookup_name($passwd, $name);
213 die("account[$name] already exists in '$path'") if defined($e);
215 my $uid = passwd_get_free_uid($passwd);
216 my $gid = 65534;# nogroup gid
218 my $pwent = $name.":x:".$uid.":".$gid.":".$name." gecos:/nodir:/bin/false";
220 passwd_add_entry($passwd, $pwent);
222 passwd_save($passwd);
224 return 0;
227 sub passwd_delete($$)
229 my ($path, $name) = @_;
231 #print "passwd_delete: '$name' in '$path'\n";
233 my $passwd = passwd_load($path);
235 my $e = passwd_lookup_name($passwd, $name);
236 die("account[$name] does not exists in '$path'") unless defined($e);
238 passwd_remove_entry($passwd, $e);
240 passwd_save($passwd);
242 return 0;
245 sub group_add($$)
247 my ($path, $name) = @_;
249 #print "group_add: '$name' in '$path'\n";
251 die("group_add: not implemented yet!");
253 return 0;
256 sub group_delete($$)
258 my ($path, $name) = @_;
260 #print "group_delete: '$name' in '$path'\n";
262 die("group_delete: not implemented yet!");
264 return 0;