summaryrefslogtreecommitdiffstats
path: root/source4/setup/newuser.pl
blob: a38067219e678af1206749c0b294728c86636741 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/usr/bin/perl -w
# simple hack script to add a new user for Samba4


use strict;
use Socket;
use Getopt::Long;

my $opt_password;
my $opt_username;
my $opt_unixname;
my $opt_samdb = "/usr/local/samba/private/sam.ldb";


# generate a random guid. Not a good algorithm.
sub randguid()
{
	my $r1 = int(rand(2**32));
	my $r2 = int(rand(2**16));
	my $r3 = int(rand(2**16));
	my $r4 = int(rand(2**16));
	my $r5 = int(rand(2**32));
	my $r6 = int(rand(2**16));
	return sprintf("%08x-%04x-%04x-%04x-%08x%04x", $r1, $r2, $r3, $r4, $r5, $r6);
}

# generate a random password. Poor algorithm :(
sub randpass()
{
	my $pass = "";
	my $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ%\$!~";
	for (my $i=0;$i<8;$i++) {
		my $c = int(rand(length($chars)));
		$pass .= substr($chars, $c, 1);
	}
	return $pass;
}

sub search($$)
{
	my $expr = shift;
	my $attrib = shift;
	my $res = `ldbsearch -H $opt_samdb \"$expr\" $attrib | grep ^$attrib | cut -d' ' -f2- | head -1`;
	chomp $res;
	return $res;
}

############################################
# show some help
sub ShowHelp()
{
	print "
Samba4 newuser

newuser.pl [options]
  --username  USERNAME     choose new username
  --password  PASSWORD     set password
  --samdb     DBPATH       path to sam.ldb

You must provide at least a username

";
	exit(1);
}

my $opt_help;

GetOptions(
	    'help|h|?' => \$opt_help, 
	    'username=s' => \$opt_username,
	    'unixname=s' => \$opt_unixname,
	    'password=s' => \$opt_password,
	    'samdb=s' => \$opt_samdb
	    );

if ($opt_help || !$opt_username) {
	ShowHelp();
}

if (!$opt_password) {
	$opt_password = randpass();
	print "chose random password '$opt_password'\n";
}

if (!$opt_unixname) {
	$opt_unixname = $opt_username;
}

my $res = "";

# allow provisioning to be run from the source directory
$ENV{"PATH"} .= ":bin:../bin";

$ENV{"LDB_URL"} = $opt_samdb;

my $domain_sid = search("(objectClass=domainDNS)", "objectSid");
my $domain_dn = search("(objectClass=domainDNS)", "dn");

my $ldif = `ldbsearch -H $opt_samdb 'cn=TemplateUser' | grep -v Template | grep -v '^#'`;
chomp $ldif;

my $sid;

# crude way of working out a rid
for (my $i=1001;$i<1100;$i++) {
	if (search("objectSid=$domain_sid-$i","objectSid") eq "") {
		$sid = "$domain_sid-$i";
		last;
	}
}

print "Chose new SID $sid\n";

my $dom_users = search("name=Domain Users", "dn");


$ldif .= "sAMAccountName: $opt_username\n";
$ldif .= "name: $opt_username\n";
$ldif .= "objectSid: $sid\n";
$ldif .= "objectGUID: " . randguid() . "\n";
$ldif .= "memberOf: $dom_users\n";
$ldif .= "userAccountControl: 0x10200\n";
$ldif .= "sAMAccountType: 0x30000000\n";
$ldif .= "objectClass: user\n";
$ldif .= "unicodePwd: $opt_password\n";
$ldif .= "unixName: $opt_unixname\n";

my $user_dn = "CN=$opt_username,CN=Users,$domain_dn";

open FILE, ">newuser.ldif";
print FILE "dn: $user_dn";
print FILE "$ldif\n";
close FILE;

open FILE, ">modgroup.ldif";
print FILE "
dn: CN=Domain Users,CN=Users,$domain_dn
changetype: modify
add: member
member: $user_dn
";
close FILE;

system("ldbadd newuser.ldif");
system("ldbmodify modgroup.ldif");