[Patch] Initial support for samba v3.0
Graham Leggett <[email protected]> Thu, 11 Mar 2004 02:01:14 +0200
| Newsgroups | gmane.network.directoryadmin |
|---|---|
| Message-ID | <[email protected]> |
Hi all, I have created a patch with initial support for the Samba v3.0 schema. The RID/SID handling has changed in v3.0. What I have done is created a function inside users.c called diradmin_user_sambadomains_from_ldap(), which queries the server for all sambaDomain objects. A second function called diradmin_user_get_sambasid_from_ldap() works out the SID of the user, given the name of the domain to which they belong. Ideally the first function should allow a dropdown box to appear giving a list of domains to which the user might belong. I could not get glade-2 to recognise the directory_administrator.glade file, so I left it to simply choose the first domain found in the LDAP server. The recipe for calculating SIDs from uids was kept at (uid * 2) + 1000, I don't know what Samba v3.0's official recipe is for creating SIDs, anyone know? Regards, Graham --
schema.h
(text/plain, 2.6 KB)
/* Copyright (C) 2004 Graham Leggett (minfrin) This file is part of Directory administrator. Directory administrator is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. Directory administrator is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Directory administrator; if not, send e-mail to [email protected] */ #ifndef __schema #define __schema 1 #define SAMBA_3_0 /* support for Samba v2.2 */ #ifdef SAMBA_2_2 #define SAMBA_LM_PASSWORD "lmPassword" #define SAMBA_NT_PASSWORD "ntPassword" #define SAMBA_ACCT_FLAGS "acctFlags" #define SAMBA_PWD_LAST_SET "pwdLastSet" #define SAMBA_LOGON_TIME "logonTime" #define SAMBA_LOGOFF_TIME "logoffTime" #define SAMBA_KICKOFF_TIME "kickoffTime" #define SAMBA_PWDCANCHANGE "pwdCanChange" #define SAMBA_PWDMUSTCHANGE "pwdMustChange" #define SAMBA_HOME_DRIVE "homeDrive" #define SAMBA_LOGIN_SCRIPT "scriptPath" #define SAMBA_PROFILE_PATH "profilePath" #define SAMBA_USER_WORKSTATIONS "userWorkstations" #define SAMBA_HOME_PATH "smbHome" #define SAMBA_DOMAIN_NAME "domain" #define SAMBA_MUNGED_DIAL "" #define SAMBA_SID "rid" #define SAMBA_PRIMARY_GROUP_SID "primaryGroupID" #define SAMBA_SAM_ACCOUNT "sambaAccount" #endif /* support for Samba v3.0 */ #ifdef SAMBA_3_0 #define SAMBA_LM_PASSWORD "sambaLMPassword" #define SAMBA_NT_PASSWORD "sambaNTPassword" #define SAMBA_ACCT_FLAGS "sambaAcctFlags" #define SAMBA_PWD_LAST_SET "sambaPwdLastSet" #define SAMBA_LOGON_TIME "sambaLogonTime" #define SAMBA_LOGOFF_TIME "sambaLogoffTime" #define SAMBA_KICKOFF_TIME "sambaKickoffTime" #define SAMBA_PWDCANCHANGE "sambaPwdCanChange" #define SAMBA_PWDMUSTCHANGE "sambaPwdMustChange" #define SAMBA_HOME_DRIVE "sambaHomeDrive" #define SAMBA_LOGIN_SCRIPT "sambaLogonScript" #define SAMBA_PROFILE_PATH "sambaProfilePath" #define SAMBA_USER_WORKSTATIONS "sambaUserWorkstations" #define SAMBA_HOME_PATH "sambaHomePath" #define SAMBA_DOMAIN "sambaDomain" #define SAMBA_DOMAIN_NAME "sambaDomainName" #define SAMBA_MUNGED_DIAL "sambaMungedDial" #define SAMBA_SID "sambaSID" #define SAMBA_ALGORITHMIC_RID_BASE "sambaAlgorithmicRidBase" #define SAMBA_PRIMARY_GROUP_SID "sambaPrimaryGroupSID" #define SAMBA_SAM_ACCOUNT "sambaSamAccount" #endif #endif
samba-3-patch
(text/plain, 16.5 KB)
Only in directory_administrator-1.5.1-new: config.h
Only in directory_administrator-1.5.1-new: config.log
Only in directory_administrator-1.5.1-new: config.status
Only in directory_administrator-1.5.1-new/macros: Makefile
Only in directory_administrator-1.5.1-new: Makefile
Only in directory_administrator-1.5.1-new/src: appfunctions.o
Only in directory_administrator-1.5.1-new/src: callbacks.o
Only in directory_administrator-1.5.1-new/src: charset.o
Only in directory_administrator-1.5.1-new/src: connect_dialog.o
Only in directory_administrator-1.5.1-new/src: .deps
Only in directory_administrator-1.5.1-new/src: directory_administrator
Only in directory_administrator-1.5.1-new/src: dir_entry.o
Only in directory_administrator-1.5.1-new/src: groups.o
Only in directory_administrator-1.5.1-new/src: icon_entry.o
Only in directory_administrator-1.5.1-new/src: interface.o
Only in directory_administrator-1.5.1-new/src: ldaptransaction.o
Only in directory_administrator-1.5.1-new/src: main.o
Only in directory_administrator-1.5.1-new/src: Makefile
Only in directory_administrator-1.5.1-new/src: md4.o
Only in directory_administrator-1.5.1-new/src: md5.o
Only in directory_administrator-1.5.1-new/src: mkntpwd.o
diff -r -u directory_administrator-1.5.1/src/modifydialogs.c directory_administrator-1.5.1-new/src/modifydialogs.c
--- directory_administrator-1.5.1/src/modifydialogs.c 2003-06-12 14:43:35.000000000 +0200
+++ directory_administrator-1.5.1-new/src/modifydialogs.c 2004-03-11 01:37:50.000000000 +0200
@@ -24,6 +24,7 @@
#include "appfunctions.h"
#include "modifydialogs.h"
#include "ldaptransaction.h"
+#include "schema.h"
void
fill_modifyuser (GtkWidget * modifyuserdialog, char *userdn)
@@ -73,10 +74,10 @@
attributes2fill = g_list_append (attributes2fill, "shadowinactive");
attributes2fill = g_list_append (attributes2fill, "title");
attributes2fill = g_list_append (attributes2fill, "ou");
- attributes2fill = g_list_append (attributes2fill, "smbHome");
- attributes2fill = g_list_append (attributes2fill, "homeDrive");
- attributes2fill = g_list_append (attributes2fill, "profilePath");
- attributes2fill = g_list_append (attributes2fill, "scriptPath");
+ attributes2fill = g_list_append (attributes2fill, SAMBA_HOME_PATH);
+ attributes2fill = g_list_append (attributes2fill, SAMBA_HOME_DRIVE);
+ attributes2fill = g_list_append (attributes2fill, SAMBA_PROFILE_PATH);
+ attributes2fill = g_list_append (attributes2fill, SAMBA_LOGIN_SCRIPT);
attributes2fill =
g_list_append (attributes2fill, "physicaldeliveryofficename");
attributes2fill = g_list_append (attributes2fill, "l");
@@ -154,7 +155,7 @@
FALSE);
}
- if (diradmin_user_has_objectclass (user, "sambaAccount"))
+ if (diradmin_user_has_objectclass (user, SAMBA_SAM_ACCOUNT))
gtk_toggle_button_set_active ((GtkToggleButton *)
lookup_widget (modifyuserdialog,
"enablesambaobjectclass"),
Only in directory_administrator-1.5.1-new/src: modifydialogs.c~
Only in directory_administrator-1.5.1-new/src: modifydialogs.o
Only in directory_administrator-1.5.1-new/src: newdruids.o
Only in directory_administrator-1.5.1-new/src: pairs.o
Only in directory_administrator-1.5.1-new/src: prefsdialog.o
Only in directory_administrator-1.5.1-new/src: prefs.o
Only in directory_administrator-1.5.1-new/src: profile.o
Only in directory_administrator-1.5.1-new/src: schema.h
Only in directory_administrator-1.5.1-new/src: smbdes.o
Only in directory_administrator-1.5.1-new/src: support.o
Only in directory_administrator-1.5.1-new/src: usergrouplists.o
diff -r -u directory_administrator-1.5.1/src/users.c directory_administrator-1.5.1-new/src/users.c
--- directory_administrator-1.5.1/src/users.c 2003-06-12 13:20:29.000000000 +0200
+++ directory_administrator-1.5.1-new/src/users.c 2004-03-11 01:21:44.000000000 +0200
@@ -34,6 +34,7 @@
#include <sys/time.h>
#include <unistd.h>
#include "md5.h"
+#include "schema.h"
//standard attributes to check on creation/modification
gchar *attrs2chk[] = { "uid", "uidnumber", "gidnumber", "givenname",
@@ -45,8 +46,8 @@
"shadowexpire", "title", "physicaldeliveryofficename",
"ou", "l",
"telephonenumber", "facsimiletelephonenumber", "o", "homephone",
- "mobile", "smbHome", "homeDrive", "profilePath", "scriptPath", "lmPassword",
- "ntPassword", "rid", "objectclass", "host","employeeNumber",
+ "mobile", SAMBA_HOME_PATH, SAMBA_HOME_DRIVE, SAMBA_PROFILE_PATH, SAMBA_LOGIN_SCRIPT, SAMBA_LM_PASSWORD,
+ SAMBA_NT_PASSWORD, SAMBA_SID, "objectclass", "host","employeeNumber",
NULL
};
@@ -57,8 +58,8 @@
"shadowinactive", "shadowexpire", NULL
};
gchar *sambalist[] = {
- "smbHome", "homeDrive", "profilePath", "scriptPath", "lmPassword",
- "ntPassword", "rid", NULL
+ SAMBA_HOME_PATH, SAMBA_HOME_DRIVE, SAMBA_PROFILE_PATH, SAMBA_LOGIN_SCRIPT, SAMBA_LM_PASSWORD,
+ SAMBA_NT_PASSWORD, SAMBA_SID, NULL
};
gchar *maillist[] = {
"maillocaladdress", "mailroutingaddress", "mailhost", NULL
@@ -74,7 +75,7 @@
gchar *handled_objectclasses[] = {
/*"person",*/"organizationalPerson","inetOrgPerson","account","posixAccount",
-"shadowAccount","sambaAccount","inetLocalMailRecipient","top", NULL
+"shadowAccount",SAMBA_SAM_ACCOUNT,"inetLocalMailRecipient","top", NULL
};
@@ -245,7 +246,7 @@
for (i = 0; sambalist[i] != NULL; i++)
if (g_strcasecmp (sambalist[i], attr) == 0)
{
- diradmin_user_add_objectclass (conn, "sambaAccount");
+ diradmin_user_add_objectclass (conn, SAMBA_SAM_ACCOUNT);
}
for (i = 0; maillist[i] != NULL; i++)
if (g_strcasecmp (maillist[i], attr) == 0)
@@ -293,7 +294,7 @@
if (isneeded == FALSE)
{
// g_print("\nTighten objectclasses: removing samba classes");
- diradmin_user_remove_objectclass (u, "sambaAccount");
+ diradmin_user_remove_objectclass (u, SAMBA_SAM_ACCOUNT);
}
isneeded = FALSE;
for (i = 0; personlist[i] != NULL; i++)
@@ -351,17 +352,17 @@
snprintf (buf2, sizeof buf2, "%s", to);
}
- if (diradmin_user_has_objectclass(conn,"sambaaccount"))
+ if (diradmin_user_has_objectclass(conn, SAMBA_SAM_ACCOUNT))
{
char hash[17], hexstr[33];
mklmhash(to, hash);
to_hexstr(hash, hexstr);
- diradmin_user_set_attribute (conn, "lmPassword", hexstr);
+ diradmin_user_set_attribute (conn, SAMBA_LM_PASSWORD, hexstr);
mknthash(to, hash);
to_hexstr(hash, hexstr);
- diradmin_user_set_attribute (conn, "ntPassword", hexstr);
+ diradmin_user_set_attribute (conn, SAMBA_NT_PASSWORD, hexstr);
}
diradmin_user_set_attribute (conn, "userPassword", buf);
if (preferences.rfc2307bis == TRUE)
@@ -502,6 +503,188 @@
}
+/**
+ * Get the list of samba domains from the ldap server.
+ *
+ * This function queries the LDAP server for all entries
+ * containing the sambaDomain objectclass, and returns
+ * a list of sambaDomainName values.
+ */
+GList *
+diradmin_user_sambadomains_from_ldap (connection_profile * usethisone)
+{
+ //conn should already be connected, or else undefined behaviour!!!
+
+ int ldap_errors;
+
+ GList *sambaDomains = NULL;
+
+ LDAP *h;
+ LDAPMessage *searchresults = NULL;
+ LDAPMessage *entry = NULL;
+
+ char **value_collection = NULL;
+
+ gchar *attribute;
+ BerElement *attributehandler;
+ gchar *attributetoreturn[2];
+ attributetoreturn[0] = SAMBA_DOMAIN_NAME;
+ attributetoreturn[1] = NULL;
+
+ g_print ("\nFetching samba domains from directory with base %s\n", usethisone->treeroot);
+
+ //check 4 connection
+ h = connection_profile_get_ldap_handler (usethisone);
+ g_assert (h);
+
+ //look data up
+ ldap_errors =
+ ldap_search_s (h, usethisone->treeroot, LDAP_SCOPE_SUBTREE, "(objectclass=" SAMBA_DOMAIN ")", attributetoreturn, 0,
+ &searchresults);
+
+ if (ldap_errors)
+ {
+ //any error?
+ g_print ("LDAP error while searching for samba domains");
+ g_print (": ");
+ g_print (ldap_err2string (ldap_errors));
+ g_print ("\n");
+ //ldap_msgfree (searchresults);
+ if (ldap_errors == LDAP_SERVER_DOWN) {
+ connection_profile_invalidate(usethisone);
+ }
+ return NULL;
+ }
+ else
+ {
+ // loop through any entries found
+ entry = ldap_first_entry (h, searchresults);
+ while (entry) {
+ attribute = ldap_first_attribute (h, entry, &attributehandler);
+ value_collection = ldap_get_values (h, entry, attribute);
+ g_assert (value_collection);
+ sambaDomains = g_list_append (sambaDomains, g_strdup (value_collection[0]));
+ g_print ("diradmin_user_sambadomains_from_ldap found samba domain: %s\n", value_collection[0]);
+ ldap_value_free (value_collection);
+ entry = ldap_next_entry (h, searchresults);
+ }
+
+ ldap_msgfree (searchresults);
+ }
+
+ return (sambaDomains);
+}
+
+
+/**
+ * Calculate the sambaSID attribute
+ *
+ * This function queries the LDAP server for the given
+ * sambaDomain objectclass specified by the sambaDomainName
+ * provided.
+ *
+ * The given uid is added to the value of sambaAlgorithmicRidBase,
+ * which in turn is tacked onto the end of sambaSID, giving the
+ * resulting value for sambaSID for this object.
+ */
+gchar *
+diradmin_user_get_sambasid_from_ldap (connection_profile * usethisone, gchar *sambaDomain, gchar *uidnumber)
+{
+ //conn should already be connected, or else undefined behaviour!!!
+
+ int ldap_errors;
+
+ LDAP *h;
+ LDAPMessage *searchresults = NULL;
+ LDAPMessage *entry = NULL;
+
+ char **value_collection = NULL;
+
+ gchar *attribute;
+ gchar *filter;
+ gchar *sambaAlgorithmicRidBase = NULL;
+ gchar *sambaSID = NULL;
+ gchar *userSambaSID = NULL;
+ char buffer[11];
+ BerElement *attributehandler;
+ gchar *attributetoreturn[3];
+ attributetoreturn[0] = SAMBA_ALGORITHMIC_RID_BASE;
+ attributetoreturn[1] = SAMBA_SID;
+ attributetoreturn[2] = NULL;
+
+ filter = g_strconcat ("(&(objectclass=" SAMBA_DOMAIN ")(" SAMBA_DOMAIN_NAME "=", sambaDomain, "))", NULL);
+ g_print ("\nFetching sambaDomain %s from directory with base %s using filter:\n%s\n\n", sambaDomain, usethisone->treeroot, filter);
+
+ //check 4 connection
+ h = connection_profile_get_ldap_handler (usethisone);
+ g_assert (h);
+
+ //look data up
+ ldap_errors =
+ ldap_search_s (h, usethisone->treeroot, LDAP_SCOPE_SUBTREE, filter, attributetoreturn, 0,
+ &searchresults);
+
+ if (ldap_errors)
+ {
+ //any error?
+ g_print ("LDAP error while searching for sambaDomain");
+ g_print (": ");
+ g_print (ldap_err2string (ldap_errors));
+ g_print ("\n");
+ //ldap_msgfree (searchresults);
+ if (ldap_errors == LDAP_SERVER_DOWN) {
+ connection_profile_invalidate(usethisone);
+ }
+ return NULL;
+ }
+ else
+ {
+ // loop through any entries found, extract attributes
+ entry = ldap_first_entry (h, searchresults);
+ while (entry) {
+ attribute = ldap_first_attribute (h, entry, &attributehandler);
+ while (attribute) {
+ value_collection = ldap_get_values (h, entry, attribute);
+ g_assert (value_collection);
+ g_print ("diradmin_user_get_sambasid_from_ldap processing: %s\n", attribute);
+ if (g_strcasecmp (attribute, SAMBA_ALGORITHMIC_RID_BASE) == 0) {
+ sambaAlgorithmicRidBase = g_strdup(value_collection[0]);
+ g_print ("diradmin_user_get_sambasid_from_ldap found sambaAlgorithmicRidBase: %s\n", sambaAlgorithmicRidBase);
+ }
+ else if (g_strcasecmp (attribute, SAMBA_SID) == 0) {
+ sambaSID = g_strdup(value_collection[0]);
+ g_print ("diradmin_user_get_sambasid_from_ldap found sambaSID: %s\n", sambaSID);
+ }
+ ldap_value_free (value_collection);
+ attribute = ldap_next_attribute (h, entry, attributehandler);
+ }
+ entry = ldap_next_entry (h, searchresults);
+ }
+
+ ldap_msgfree (searchresults);
+ }
+
+ // sanity check
+ if (!sambaSID) {
+ g_print ("diradmin_user_get_sambasid_from_ldap found sambaDomain %s, but this object had no sambaSID attribute associated with it.\n", sambaDomain);
+ return NULL;
+ }
+ if (!sambaAlgorithmicRidBase) {
+ g_print ("diradmin_user_get_sambasid_from_ldap found sambaDomain %s, but this object had no sambaAlgorithmicRidBase attribute associated with it.\n", sambaDomain);
+ return NULL;
+ }
+
+ // create sambaSID of user or group
+ sprintf(buffer, "%d", 2*atoi(uidnumber) + atoi(sambaAlgorithmicRidBase));
+ userSambaSID = g_strconcat(sambaSID, "-", buffer, NULL);
+ g_free(sambaSID);
+ g_free(sambaAlgorithmicRidBase);
+ g_print ("diradmin_user_get_sambasid_from_ldap returned %s\n", userSambaSID);
+ return userSambaSID;
+}
+
+
+
GList *
diradmin_user_get_allowedservers (diradmin_user * conn)
{
@@ -836,7 +1019,7 @@
{
oldattr = diradmin_user_get_attribute (oldone, attrs2chk[acnt]);
newattr = diradmin_user_get_attribute (newone, attrs2chk[acnt]);
- ispassword = g_strcasecmp (attrs2chk[acnt], "userPassword") == 0 || g_strcasecmp (attrs2chk[acnt], "authPassword") == 0 || g_strcasecmp (attrs2chk[acnt], "ntPassword") == 0 || g_strcasecmp (attrs2chk[acnt], "lmPassword") == 0;
+ ispassword = g_strcasecmp (attrs2chk[acnt], "userPassword") == 0 || g_strcasecmp (attrs2chk[acnt], "authPassword") == 0 || g_strcasecmp (attrs2chk[acnt], SAMBA_NT_PASSWORD) == 0 || g_strcasecmp (attrs2chk[acnt], SAMBA_LM_PASSWORD) == 0;
// if any attribute isn't empty
if (oldattr || newattr) {
@@ -911,12 +1094,12 @@
gchar *shadowmin = NULL;
gchar *shadowmax = NULL;
gchar *shadowwarning = NULL;
- gchar *smbHome = NULL;
- gchar *homeDrive = NULL;
- gchar *profilePath = NULL;
- gchar *scriptPath = NULL;
- gchar *lmPassword = NULL;
- gchar *ntPassword = NULL;
+ gchar *sambaHomePath = NULL;
+ gchar *sambaHomeDrive = NULL;
+ gchar *sambaProfilePath = NULL;
+ gchar *sambaLoginScript = NULL;
+ gchar *sambaLMPassword = NULL;
+ gchar *sambaNTPassword = NULL;
gchar *shadowinactive = NULL;
char buf[32];
@@ -957,10 +1140,10 @@
gtk_entry_get_text (GTK_ENTRY
(lookup_widget (dialogbox, "userpassword")));
- lmPassword =
+ sambaLMPassword =
gtk_entry_get_text (GTK_ENTRY
(lookup_widget (dialogbox, "userpassword")));
- ntPassword =
+ sambaNTPassword =
gtk_entry_get_text (GTK_ENTRY
(lookup_widget (dialogbox, "userpassword")));
gecos = gtk_entry_get_text (GTK_ENTRY (lookup_widget (dialogbox, "cn")));
@@ -1096,26 +1279,49 @@
if (GTK_TOGGLE_BUTTON
(lookup_widget (dialogbox, "enablesambaobjectclass"))->active)
{
+#ifdef SAMBA_2_2
char rid[11];
+#else
+ GList *sambaDomains;
+ GList *iterator;
+ gchar *sambaDomain;
+#endif
+
+ sambaDomain =
+ gtk_entry_get_text (GTK_ENTRY (lookup_widget (dialogbox, "sambadomain")));
- smbHome =
+ sambaHomePath =
gtk_entry_get_text (GTK_ENTRY (lookup_widget (dialogbox, "smbHome")));
- homeDrive =
+ sambaHomeDrive =
gtk_entry_get_text (GTK_ENTRY
(lookup_widget (dialogbox, "homeDrive")));
- profilePath =
+ sambaProfilePath =
gtk_entry_get_text (GTK_ENTRY
(lookup_widget (dialogbox, "profilePath")));
- scriptPath =
+ sambaLoginScript =
gtk_entry_get_text (GTK_ENTRY
(lookup_widget (dialogbox, "scriptPath")));
- diradmin_user_set_attribute (newuser, "smbHome", smbHome);
- diradmin_user_set_attribute (newuser, "homeDrive", homeDrive);
- diradmin_user_set_attribute (newuser, "profilePath", profilePath);
- diradmin_user_set_attribute (newuser, "scriptPath", scriptPath);
+ diradmin_user_set_attribute (newuser, SAMBA_HOME_PATH, sambaHomePath);
+ diradmin_user_set_attribute (newuser, SAMBA_HOME_DRIVE, sambaHomeDrive);
+ diradmin_user_set_attribute (newuser, SAMBA_PROFILE_PATH, sambaProfilePath);
+ diradmin_user_set_attribute (newuser, SAMBA_LOGIN_SCRIPT, sambaLoginScript);
+#ifdef SAMBA_2_2
sprintf(rid, "%d", 2*atoi(uidnumber) + 1000);
- diradmin_user_set_attribute (newuser, "rid", rid);
+ diradmin_user_set_attribute (newuser, SAMBA_SID, rid);
+#else
+// NOTE: This code currently assumes there is a single domain. If there
+// is more than one domain, then the first domain is used.
+// What should probably happen is the "windows domain" should be selected
+// from a drop down menu.
+ sambaDomains = diradmin_user_sambadomains_from_ldap(conn);
+ iterator = g_list_first(sambaDomains);
+ g_assert(iterator);
+ sambaDomain = iterator->data;
+ g_assert(sambaDomain);
+ diradmin_user_set_attribute (newuser, SAMBA_SID, diradmin_user_get_sambasid_from_ldap(conn, sambaDomain, uidnumber));
+ diradmin_user_set_attribute (newuser, SAMBA_DOMAIN, sambaDomain);
+#endif
}
if (strlen (userpassword) > 0)
Only in directory_administrator-1.5.1-new/src: users.o
Only in directory_administrator-1.5.1-new: stamp-h1