[Samba] Re: Simple question - Machine / User relationsip
Jim C
jcllings at tsunamicomm.net
Wed Jan 22 05:13:01 GMT 2003
I've solved this and a few other issues.
Since a computer is a user (effectively), it must have a unique
uidNumber (regardless of whether or not it lives in a different ou) and
properly calculated rid and primaryGroupID attributes. I've found that
the scripts provided do not do an adequate job in this regards. There
is also a problem with getting the largest uidNumber from the system so
that you can add 1 to it and set it as the uid for the new user.
What I did to solve this was add objectcalss's uidPool and gidPool to my
proxyuser. This results in the addition of attributes uidNumber and
gidNumber to the proxyuser. I then wrote a script to get the values of
the largest uidNumber and the largest gidNumber and leave these values
in the proxyuser's uidNumber and gidNumber. Then I wrote another that
adds one to those numbers and then updates the proxyuser with the new
numbers. Then in the script, I take the numbers and use them to build a
new machine user.
I can send you the script but it will need modification. For one thing
it has to have the root dn's password and of course it needs to know
where everything is. I tried to put all of this at the top for ease of
adaptation. It is written in php.
I also discovered that /etc/ldap.conf on the server is not just for
Linux's use locally. When the system goes looking for *any* uid, it
looks for the posix settings first in the ou specified in ldap.conf.
That means that as far as the OS is concerned EVERY user is a posix
user. Consequently it cannot find users who do not exist in an ou
spec'ed out in /etc/ldap.conf (i.e. ou=Computers is not in there) I now
have my ldap.conf like so:
# The port.
# Optional: default is 389.
#port 389
# The search scope.
scope sub
#scope one
#scope base
and then later:
nss_base_passwd dc=microverse,dc=net?sub
nss_base_shadow dc=microverse,dc=net?sub
nss_base_group ou=Group,dc=microverse,dc=net?one
nss_base_hosts ou=Hosts,dc=microverse,dc=net?one
Basically this tells the system to start in dc=microverse,dc=net to look
for password and shadow type records. It proceeds to search every ou
that exists at the dc=microverse,dc=net level for values of this type
which basically means that it will be able to find our computers located
in ou=Computers. Previously these were set to ou=People?one which means
it will only look in People. It might be better though, for efficiency,
if one made an ou=Usr and then put ou=People and ou=Computers
underneath. Then we can limit our passwd and shadow searches to ou=Usr.
Also don't forget that if you add an ou=Computers that you specifically
grant your root user read/write privileges to it. Might also be good to
give the proxyuser read access. Notice what I've done to protect the
lmPassword and ntPassword attributes.
Here is the slapd.access.conf I am using:
# This is a good place to put slapd access-control directives
access to dn=".*,dc=microverse,dc=net" attr=*
by dn="cn=root,dc=microverse,dc=net" write
access to dn=".*,dc=microverse,dc=net" attr=userPassword
by dn="cn=root,dc=microverse,dc=net" write
by dn="cn=Administrator,ou=People,dc=microverse,dc=net" write
by dn="cn=proxyuser,dc=microverse,dc=net" read
by self write
by * auth
access to dn=".*,dc=microverse,dc=net" attrs=lmPassword,ntPassword
by dn="cn=root,dc=microverse,dc=net" write
by dn="uid=Administrator,ou=People,dc=microverse,dc=net" write
by self write
by * auth
access to dn=".*,dc=microverse,dc=net" attr=mail
by dn="cn=root,dc=microverse,dc=net" write
by dn="cn=Administrator,ou=People,dc=microverse,dc=net" write
by self write
by * read
access to dn=".*,ou=People,dc=microverse,dc=net"
by * read
access to dn=".*,ou=Computers,dc=microverse,dc=net"
by * read
access to dn=".*,dc=microverse,dc=net"
by self write
by * read
Bas Goes wrote:
>
> Hi Jim,
>
> I have had the exact same problem and didn't find a solution, now i am
> looking at samba tng, but that one won't compile and I'd rather use
> samba. If you have a solution or an idea, i would be quite grateful if
> you share it with me.
>
> Thanks in advance.
>
> Regards,
>
> Bas
>
>
>
-------------- next part --------------
<?php
/*
This script takes one parameter. A userid.
Place it in smb.conf as the add user script like so:
add user script = php /usr/share/samba/scripts/addmachine.php %u
You can also test it from the command line like so:
php addmachine.php freddycruegar
Samba will append the "$" as required.
The maximum uidNumber value must also be held in proxyuser's uidNumber in
order for this to work.
*/
// basic sequence with LDAP is connect, bind, search, interpret search
// result, close connection
$machine=trim($argv[1]);
define(LDAPSERVER,"localhost");
define(PROXYDN,"cn=proxyuser,dc=microverse,dc=net");
define(ROOTDN,"cn=root,dc=microverse,dc=net");
define(ROOTPW,"placepasswordhere"); //<<<-------Need rootdn's PW.
define(LDAPBASE,"dc=microverse,dc=net");
define(MINUID, 500);
//The group "Machines" as mentioned below on my system is group 421.
define(MACHINEGROUP,"421");
define(NUMRETRIES, 4);
/*
This function grabs the number of the greatest uid value in the system from
proxyuser's uidNumber and then increments it and updates proxyuser.
We then take the number and use it to make a new account since this new number
is, in theory, unique.
*/
function getnewuid ($ds) {
$booleantest=FALSE;
//We get a number of retries equal to NUMRTRIES
for($idx=0; $idx < NUMRETRIES && !$booleantest ;$idx=$idx+1 )
{
$entries=ldap_get_entries($ds, ldap_search($ds, PROXYDN ,"cn=*"));
/*
If another such script starts and finishes it's ldap_mod_replace before
we get ours started right here at this point, then we have a race condition
at the script level. This is why I've tried to condense this part as
much as possible.
Nothing to be done about this. As far as I can tell there is no way
to lock attributes or records in php-ldap.
*/
//Watch out. In some cases like below "uidnumber" must be all lowercase.
if($entries[0]["uidnumber"][0] < MINUID )
$change_entry["uidnumber"] = MINUID;
else
$change_entry["uidnumber"] = $entries[0]["uidnumber"][0] + 1;
//This, at least, is atomic.
$booleantest=ldap_mod_replace($ds, PROXYDN, $change_entry);
}
if($booleantest)
return $change_entry["uidnumber"];
else
die("Timeout error! Unable to set uidNumber in PROXYDN. To many users being added from other sources?\n");
}//end of function getnewuid ($ds)
//echo "LDAP query test\n";
//echo "Connecting ...\n";
$ds=ldap_connect(LDAPSERVER); // must be a valid LDAP server!
//echo "connect result is ".$ds."\n";
if ($ds) {
//echo "Binding ...";
$r=ldap_bind($ds,ROOTDN,ROOTPW);
//echo "Bind result is ".$r."\n";
} else die( "Unable to connect to LDAP server!\n");
/*
Despite the fact that this is not a real user we must have a password.
Below we generate one based on a random number.
*/
mt_srand((double)microtime()*1000000);
$psswrd=mt_rand();
//Change the below to match where your Computer accounts are going.
$dn = "uid=$machine,ou=Computers,dc=microverse,dc=net";
$new_object["objectClass"][0] = "top";
$new_object["objectClass"][1] = "account";
$new_object["objectClass"][2] = "posixAccount";
//$new_object["objectClass"][3] = "shadowAccount";
$new_object["uidNumber"][0] = getnewuid($ds);
$new_object["uid"][0] = $machine;
$new_object["cn"][0] = $machine;
$new_object["gidNumber"][0] = MACHINEGROUP;
$new_object["homeDirectory"][0] = "/dev/null";
$new_object["loginShell"][0] = "/bin/false";
$new_object["gecos"][0] = "Machine Account";
$new_object["description"][0] = "Machine Account";
$new_object["userPassword"][0] = `slappasswd -h {CRYPT} -s $psswrd`;
//Samba takes care of the rest of the attributes. They are calculated
//based on these.
if(!ldap_add($ds, $dn, $new_object))
{
ldap_close($ds);
die("Error! Could not add new user. Most likely someone already has that userid.\n");
}
//echo "\nClosing connection\n";
ldap_close($ds);
#system(escapeshellcmd("smbpasswd -a -m $username$"));
?>
More information about the samba
mailing list