What the project is about
The goal of this project was to ensure that Samba4 domain controller was aware of the GPO's that should be applied to it. If a domain configuration exists where they want the domain controllers to only have a password with minimum 6 characters, or a minimum age, than it should be applied to the Samba server Domain Controller. It should also take hierarchy into account and do this on a constant basis, and not just once when the program starts up.
Many of the tools already existed for this, and it was just a matter of putting them together in a way that it runs smoothly, and of course writing tests.
What was done so far
- Python/libgpo bindings
- Libgpo is a library that seems to be overlooked in Samba4 and is usually used to get GPO from remote server. The first step was creating python/c bindings for this library so that functions could be used within python scripts to utilize already existing tools. It meant bringing this library to life to take what was needed but in a python way.
- Sysvol scanning
- An algorithm was created to get sysvol location and scan for GPO's. First, it creates a Samba ldb object from command line with the smb.conf, then it uses the smb.conf to get sysvol. It finds the Policies folder using OS commands, so that it is able to put them through the parser then apply to samba.
- Parse GPO/update Samba.
- Using libgpo and manual .inf file handling (codecs library 'utf-16' unicoding), it maps the .inf file parameter to the Samba4 server (samdb.py). Since Samba4 uses LDAP, it used general LDAP protocol grammar.
- Do the updates automatically.
- It was designed in the same way DNS updates were. Samba4 obviously uses talloc hierarchical memory contexts, so to get the higher level tevent.h was used. This merely made it easier to get the signal to the highest level possible in Samba4 to run periodically instead of using a foreign python library to rely on as a timer.
- Take hierarchy into account
- Obviously it is not desired to have every single GPO applied to Samba4. Nor is it desired to have only the domain GPO applied. So it was necessary to ensure that GPO's have their respective precedence. So if 2 GPO's exist for Password Length, only one should win. This is decided based on the AD standard : Local, Site, Domain, then Organizational Unit. Since Samba4 currently can not create GPO's from a Linux machine, a local GPO can not be read, and sites are not thoroughly enough supported with GPO to care, at this point. Therefore only the domain and OU GPO need apply. And when they apply, a order for that container must be taken into account. This should happen each time it does this scan.
- Ignore the unimportant and unchanged GPO's
- The thread is fairly low resources. It creates a log file each time, and reads a quick log file of previous GPO located in ../sysvol/syslog.txt. If the version number has changed, so has the GPO. If the GPO is 0, then it is empty and move on. Do not read files that are .inf (.pol are 99.9% Microsoft Windows user configurations like screensaver, control panel, etc..) and update Samba if necessary.
What is left to do/known limitations
- Further the hierarchy
- For the moment, it only puts a focus on the "Domain Controllers" library. So it should be known that that is where the Samba DC should live.
- Reset DC back to default parameter values
- The service does not have a map to defaults yet. So when the GPO is deleted, it keeps the value until changed manually.
- Add event driven aspects
- For the moment the service applies based on a default time configuration (15 seconds). It should not only do it based on time, but also listen to the sysvol/realm/policies folder so that it occurs immidiatly when applied.
- More testing
- The concept of unit testing was introduced closer to the end of this project. Although a few of the main aspects were tested in gpo.py in ../samba/tests/gpo.py, a few tests still remain.
- Extend further the libgpo/python bindings
- An honest attempt was made to wrap libgpo in the time allotted at the beginning but the entire thing was not done. There were only a couple functions used from this module. There could be more coverage so that libgpo can completely be used in python, breathing more life back into this library. The project was to make the service, not to wrap libgpo, so a lot of things had to be left so other more relevant things could be focused on,
- Make a broader range of GPO applied
- This was something that I was not pleased with. Time was not generous at the end, when the service worked to look for more applied GPO's. Since most of the time, this involved changing the main Samba database (samdb.py), this would have involved understanding more this file, and minimally tweaking it to check to see if the parameter exists. Then if not, create the parameter. This is a project all on its own.
- Security Identifiers
- This was yet another aspect of GPO that can be applied. This involves the Samba database as well and needs to be taken into account. This is a several step sub-project that needs to be done.
First of all, everything that is on that TODO list will be implemented. First the default values, then smoothing out the hierarchy, then the unit testing so the service is standalone and a stronger package. Afterwards, the fun of getting in depth with python referencing/c pointer and talloc management will be done with the libgpo python bindings.
That having said this project sparked something else as well. During a unit test, I discovered that it is not hard to just create a unicoded .inf file that represents the values that a GPO contains. The GPO will also have other attributes, such as a GPLINK, a linking order, and other network related things. If one can merely create this .inf file and give it the properties and characteristics of a regular GPO (intermediate string handling with LDAP), than one could create good GPO from Linux.
This would in the slightly longer term serve to add more DC management from the Linux machine therefore eliminating a step. If Samba4 can make OU, make users, do mostly everything possible to make it a good DC, it would be nice to eliminate the step of having the windows machine to control it and simply have a Group Policy Management tool from the Linux machine. This can be done in a few different ways, one being command line (the first prototype WILL be command line), another being something like gpo.conf (replaces the windows GUI for terminal users), and the last being the GUI that would have the same qualities as the Windows version of Group Policy Manager.
This however would take some extensive research on forcing such GPO into the domain, and making sure that all machines and not just a select few clients are aware of the GPO made by the Linux machine. This could either be an ongoing study to work on, or an idea for GSoC 2014.
A look back
The amount of time and energy that was dispensed understanding truly what the project entailed was very significant. Many late hours were spent face-deep in Microsofts documentation on how Active Directory works, the protocols, how the server is employed, and what happens with GPOs. I underestimated the amount of time was required figuring out my way around the libgpo code, as there was little to no documentation for this whatsoever.
Other challenges included narrowing the scope. For Samba4 also has a registry, which is interesting, but where the GPO are configuration based in .pol files (screensaver, user based things) an executive decision was made to simply focus on the .inf files (security rules, password configurations). This project entailed many aspects of Active Directory, Linux, git, and wireshark that I was unaware of prior to doing this project. The coding served to be both the easiest, and funnest part. The modular method of attacking the problem was the hardest. Because for anyone in IT, this is a really cool project. A server side GPO, is a dream for a systems admin to implement. So a lot of it was tearing myself away from all of the minute details of AD, DC, LDAP, TCP/IP, GPO, anything that went in depth with these topics, and getting back to the project and the timeline.
However, since the service is created, tested and works, I am overall pleased with my efforts as a whole. Obviously in a 3 month period, there are a limited scope that has to be employed. Things like hierarchy were a bit more complete, and inotify failed to make the todo list. However looking back at my original proposal the main points are fulfilled, so I cannot complain.
Advise to Future GSoC in Samba
Learn to build. For coding, things like "make -j", editing wscript_build files, "make test TESTS=samba.yourtest", and anything that lets you compile. It can be abstract at first, but the sooner you can see your syntax errors, the sooner you can begin developing.
Do not be shy! Had it not been for my extreme "getting involved" and asking lots of questions, I would have wasted half of my time learning about the server/client relationship on a lower level and maybe not completed my program. The people are there to help, and keep you on track. Be open with what you are doing, because if you keep it a secret, you may focus on an aspect that is not important and waste much valuable time. Communicate!
Also if you are developing for Samba you made the right choice. In this new age of mysql, php, ruby on rails, passenger; people who understand truly what a server does are invaluable. As a person of music, I would like to say that Samba to servers is like classical is to music. It is the rawest, most visceral form of server understanding conception, yet elegant in its employment.
I jumped into this project with both feet. I woke up every morning and worked all day, every day (weekends included) until I understood something, anything. I re-sketched my timeline every few days, so that it was realistic and accurate. I sought help from system administrators at my school, masters students in computer science, watched countless youtube videos, until I honestly understood the concepts in depth. The passion to learn kept me going. I feel a lot more confident around the Samba code now thanks to Matthieu and Jelmer. I feel a lot more confident in how it works thanks to Abartlet, and RiXter. Of course thanks to the entire team on the IRC and samba-technical mailing list.
Finally I would like to thank Google and Sergey Brin and Larry Page for starting the program, Carol Smith for her great management of the 2013 program, and finally the entire Samba team and my mentor Matthieu Pattou for being great advisers making this a really enjoyable experience.