Can someone explain to me the mechanizm that Samba uses to relate Machines to Users? I am trying to set up a Samba-LDAP PDC and it seems to work OK but I get "No mapping between account names and security IDs was done." This would seem to be a simple user/group ownership/permissions thing. Now I have the following potentially pertinent ou's: People Computers Groups One would think that simply adding a group or having People become members of a group would fix the problem. What fields should I be looking at though? Where is this theoretical reltionship stored? Jim C.
What does your smb.conf look like? Jim wrote:> Can someone explain to me the mechanizm that Samba uses to relate > Machines to Users? I am trying to set up a Samba-LDAP PDC and it > seems to work OK but I get "No mapping between account names and > security IDs was done." This would seem to be a simple user/group > ownership/permissions thing. Now I have the following potentially > pertinent ou's: > > People > Computers > Groups > > One would think that simply adding a group or having People become > members of a group would fix the problem. What fields should I be > looking at though? Where is this theoretical reltionship stored? > > Jim C. > > >-- Regards, Richard Canada Assistant Computer Systems Manager Medical Research Laboratories International, USA 2 Tesseneer Drive Highland Heights, Kentucky 41076 Phone: (859) 781-8877 x266 Fax: (859) 781-9310 richard.canada@mrli.ppdi.com <mailto:richard.canada@mrli.ppdi.com> ______________________________________________________________________ This email transmission and any documents, files or previous email messages attached to it may contain information that is confidential or legally privileged. If you are not the intended recipient or a person responsible for delivering this transmission to the intended recipient, you are hereby notified that you must not read this transmission and that any disclosure, copying, printing, distribution or use of this transmission is strictly prohibited. If you have received this transmission in error, please immediately notify the sender by telephone or return email and delete the original transmission and its attachments without reading or saving in any manner. ______________________________________________________________________
I've solved this. 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$")); ?>
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$")); ?>