diff options
Diffstat (limited to 'source/passdb/pdb_ldap.c')
-rw-r--r-- | source/passdb/pdb_ldap.c | 1624 |
1 files changed, 478 insertions, 1146 deletions
diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c index a10e6f2989b..a4258347178 100644 --- a/source/passdb/pdb_ldap.c +++ b/source/passdb/pdb_ldap.c @@ -1,12 +1,11 @@ /* - Unix SMB/CIFS implementation. + Unix SMB/Netbios implementation. + Version 2.9. LDAP protocol helper functions for SAMBA - Copyright (C) Jean François Micouleau 1998 - Copyright (C) Gerald Carter 2001 - Copyright (C) Shahms King 2001 - Copyright (C) Andrew Bartlett 2002 - Copyright (C) Stefan (metze) Metzmacher 2002 - + Copyright (C) Gerald Carter 2001 + Copyright (C) Shahms King 2001 + Copyright (C) Jean François Micouleau 1998 + This program 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 of the License, or @@ -25,10 +24,7 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_PASSDB - -#ifdef HAVE_LDAP +#ifdef WITH_LDAP_SAM /* TODO: * persistent connections: if using NSS LDAP, many connections are made * however, using only one within Samba would be nice @@ -52,366 +48,201 @@ #include <lber.h> #include <ldap.h> +#ifndef LDAP_OPT_SUCCESS +#define LDAP_OPT_SUCCESS LDAP_SUCCESS +#endif + #ifndef SAM_ACCOUNT #define SAM_ACCOUNT struct sam_passwd #endif -struct ldapsam_privates { - - /* Former statics */ +struct ldap_enum_info { LDAP *ldap_struct; LDAPMessage *result; LDAPMessage *entry; int index; - - /* retrive-once info */ - const char *uri; - - BOOL permit_non_unix_accounts; - - uint32 low_nua_rid; - uint32 high_nua_rid; - - char *bind_dn; - char *bind_secret; }; +static struct ldap_enum_info global_ldap_ent; + -static struct ldapsam_privates *static_ldap_state; +extern pstring samlogon_user; +extern BOOL sam_logon_in_ssb; + +/* + * attributes needed from sambaAccount + * + * objectclass ( 1.3.6.1.4.1.7165.2.2.3 NAME 'sambaAccount' SUP top AUXILIARY + * DESC 'Samba Auxilary Account' + * MUST ( uid $ rid ) + * MAY ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $ + * logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $ + * displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $ + * description $ userWorkstations $ primaryGroupID $ domain )) + */ + +char* attribs[] = { + "uid", + "rid", + "cn", + "lmPassword", + "ntPassword", + "pwdLastSet", + "logonTime", + "logoffTime", + "kickoffTime", + "pwdCanChange", + "pwdMustChange", + "acctFlags", + "displayName", + "smbHome", + "homeDrive", + "scriptPath", + "profilePath", + "description", + "userWorkstations", + "primaryGroupID", + "domain", + NULL +}; -static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state); /******************************************************************* - find the ldap password + open a connection to the ldap server. ******************************************************************/ -static BOOL fetch_ldapsam_pw(char **dn, char** pw) +static BOOL ldap_open_connection (LDAP ** ldap_struct) { - char *key = NULL; - size_t size; + int port; + int version; + int tls, rc; + uid_t uid = geteuid(); + struct passwd* pass; - *dn = smb_xstrdup(lp_ldap_admin_dn()); + DEBUG(5,("ldap_open_connection: starting...\n")); + /* + * using sys_getpwnam() here since I'm assuming that the + * ldapsam is only used on a standalone server or PDC. + * winbind not in the picture.... + */ - if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) { - SAFE_FREE(*dn); - DEBUG(0, ("fetch_ldapsam_pw: asprintf failed!\n")); + if ( (pass=sys_getpwuid(uid)) == NULL ) { + DEBUG(0,("ldap_open_connection: Can't determine user of running process!\n")); + return False; } - - *pw=secrets_fetch(key, &size); - if (!size) { - /* Upgrade 2.2 style entry */ - char *p; - char* old_style_key = strdup(*dn); - char *data; - fstring old_style_pw; - - if (!old_style_key) { - DEBUG(0, ("fetch_ldapsam_pw: strdup failed!\n")); - return False; - } - - for (p=old_style_key; *p; p++) - if (*p == ',') *p = '/'; - - data=secrets_fetch(old_style_key, &size); - if (!size && size < sizeof(old_style_pw)) { - DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n")); - SAFE_FREE(old_style_key); - SAFE_FREE(*dn); - return False; - } - - strncpy(old_style_pw, data, size); - old_style_pw[size] = 0; - - SAFE_FREE(data); - - if (!secrets_store_ldap_pw(*dn, old_style_pw)) { - DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n")); - SAFE_FREE(old_style_key); - SAFE_FREE(*dn); - return False; - } - if (!secrets_delete(old_style_key)) { - DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n")); - } - SAFE_FREE(old_style_key); + /* check that the user is in the domain admin group for connecting */ - *pw = smb_xstrdup(old_style_pw); + if ( (uid != 0) && !user_in_list(pass->pw_name, lp_domain_admin_group()) ) { + DEBUG(0, ("ldap_open_connection: cannot access LDAP when not root or a member of domain admin group..\n")); + return False; } - - return True; -} - -static const char *attr[] = {"uid", "pwdLastSet", "logonTime", - "logoffTime", "kickoffTime", "cn", - "pwdCanChange", "pwdMustChange", - "displayName", "homeDrive", - "smbHome", "scriptPath", - "profilePath", "description", - "userWorkstations", "rid", - "primaryGroupID", "lmPassword", - "ntPassword", "acctFlags", - "domain", "description", NULL }; - -/******************************************************************* - open a connection to the ldap server. -******************************************************************/ -static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP ** ldap_struct) -{ - int version; + port = lp_ldap_port(); + + /* remap default port is no SSL */ + if ( (lp_ldap_ssl() == LDAP_SSL_OFF) && (lp_ldap_port() == 636) ) { + port = 389; + } - if (geteuid() != 0) { - DEBUG(0, ("ldap_open_connection: cannot access LDAP when not root..\n")); + DEBUG(10,("Initializing connection to %s on port %d\n", + lp_ldap_server(), port )); + + if ((*ldap_struct = ldap_init(lp_ldap_server(), port)) == NULL) { + DEBUG(0, ("The LDAP server is not responding !\n")); return False; } -#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) - DEBUG(10, ("ldapsam_open_connection: %s\n", ldap_state->uri)); - - if (ldap_initialize(ldap_struct, ldap_state->uri) != LDAP_SUCCESS) { - DEBUG(0, ("ldap_initialize: %s\n", strerror(errno))); - return (False); - } - + /* Connect to older servers using SSL and V2 rather than Start TLS */ if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) { - if (version != LDAP_VERSION3) + if (version != LDAP_VERSION2) { - version = LDAP_VERSION3; + version = LDAP_VERSION2; ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version); } } -#else - - /* Parse the string manually */ - + switch (lp_ldap_ssl()) { - int rc; - int tls = LDAP_OPT_X_TLS_HARD; - int port = 0; - fstring protocol; - fstring host; - const char *p = ldap_state->uri; - SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254); - - /* skip leading "URL:" (if any) */ - if ( strncasecmp( p, "URL:", 4 ) == 0 ) { - p += 4; - } - - sscanf(p, "%10[^:]://%254s[^:]:%d", protocol, host, &port); - - if (port == 0) { - if (strequal(protocol, "ldap")) { - port = LDAP_PORT; - } else if (strequal(protocol, "ldaps")) { - port = LDAPS_PORT; - } else { - DEBUG(0, ("unrecognised protocol (%s)!\n", protocol)); - } - } - - if ((*ldap_struct = ldap_init(host, port)) == NULL) { - DEBUG(0, ("ldap_init failed !\n")); - return False; - } - - /* Connect to older servers using SSL and V2 rather than Start TLS */ - if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) - { - if (version != LDAP_VERSION2) + case LDAP_SSL_START_TLS: +#ifdef HAVE_LDAP_START_TLS_S + if (ldap_get_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, + &version) == LDAP_OPT_SUCCESS) { - version = LDAP_VERSION2; - ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version); - } - } - - if (strequal(protocol, "ldaps")) { - if (lp_ldap_ssl() == LDAP_SSL_START_TLS) { - if (ldap_get_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, - &version) == LDAP_OPT_SUCCESS) - { - if (version < LDAP_VERSION3) - { - version = LDAP_VERSION3; - ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, - &version); - } - } - if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS) + if (version < LDAP_VERSION3) { - DEBUG(0,("Failed to issue the StartTLS instruction: %s\n", - ldap_err2string(rc))); - return False; - } - DEBUG (2, ("StartTLS issued: using a TLS connection\n")); - } else { - - if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS) - { - DEBUG(0, ("Failed to setup a TLS session\n")); + version = LDAP_VERSION3; + ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, + &version); } } - } else { + if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS) + { + DEBUG(0,("Failed to issue the StartTLS instruction: %s\n", + ldap_err2string(rc))); + return False; + } + DEBUG (2, ("StartTLS issued: using a TLS connection\n")); +#else + DEBUG(0,("ldap_open_connection: StartTLS not supported by LDAP client libraries!\n")); + return False; +#endif + break; + + case LDAP_SSL_ON: +#ifdef LDAP_OPT_X_TLS + tls = LDAP_OPT_X_TLS_HARD; + if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS) + { + DEBUG(0, ("Failed to setup a TLS session\n")); + } + + DEBUG(0,("LDAPS option set...!\n")); +#else + DEBUG(0,("ldap_open_connection: Secure connection not supported by LDAP client libraries!\n")); + return False; +#endif + break; + + case LDAP_SSL_OFF: + default: /* * No special needs to setup options prior to the LDAP * bind (which should be called next via ldap_connect_system() */ - } + break; } -#endif DEBUG(2, ("ldap_open_connection: connection opened\n")); return True; } - -/******************************************************************* - a rebind function for authenticated referrals - This version takes a void* that we can shove useful stuff in :-) -******************************************************************/ -#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) -#else -static int rebindproc_with_state (LDAP * ld, char **whop, char **credp, - int *methodp, int freeit, void *arg) -{ - struct ldapsam_privates *ldap_state = arg; - - /** @TODO Should we be doing something to check what servers we rebind to? - Could we get a referral to a machine that we don't want to give our - username and password to? */ - - if (freeit) { - SAFE_FREE(*whop); - memset(*credp, '\0', strlen(*credp)); - SAFE_FREE(*credp); - } else { - DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n", - ldap_state->bind_dn)); - - *whop = strdup(ldap_state->bind_dn); - if (!*whop) { - return LDAP_NO_MEMORY; - } - *credp = strdup(ldap_state->bind_secret); - if (!*credp) { - SAFE_FREE(*whop); - return LDAP_NO_MEMORY; - } - *methodp = LDAP_AUTH_SIMPLE; - } - return 0; -} -#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ - -/******************************************************************* - a rebind function for authenticated referrals - This version takes a void* that we can shove useful stuff in :-) - and actually does the connection. -******************************************************************/ -#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) -static int rebindproc_connect_with_state (LDAP *ldap_struct, - LDAP_CONST char *url, - ber_tag_t request, - ber_int_t msgid, void *arg) -{ - struct ldapsam_privates *ldap_state = arg; - int rc; - DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n", - ldap_state->bind_dn)); - - /** @TODO Should we be doing something to check what servers we rebind to? - Could we get a referral to a machine that we don't want to give our - username and password to? */ - - rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret); - - return rc; -} -#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ - -/******************************************************************* - Add a rebind function for authenticated referrals -******************************************************************/ -#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) -#else -# if LDAP_SET_REBIND_PROC_ARGS == 2 -static int rebindproc (LDAP *ldap_struct, char **whop, char **credp, - int *method, int freeit ) -{ - return rebindproc_with_state(ldap_struct, whop, credp, - method, freeit, static_ldap_state); - -} -# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/ -#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ - -/******************************************************************* - a rebind function for authenticated referrals - this also does the connection, but no void*. -******************************************************************/ -#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) -# if LDAP_SET_REBIND_PROC_ARGS == 2 -static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request, - ber_int_t msgid) -{ - return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid, - static_ldap_state); -} -# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/ -#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ - /******************************************************************* connect to the ldap server under system privilege. ******************************************************************/ -static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * ldap_struct) +static BOOL ldap_connect_system(LDAP * ldap_struct) { int rc; - char *ldap_dn; - char *ldap_secret; + static BOOL got_pw = False; + static pstring ldap_secret; - /* The rebind proc needs this *HACK*. We are not multithreaded, so - this will work, but it's not nice. */ - static_ldap_state = ldap_state; - - /* get the password */ - if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret)) + /* get the password if we don't have it already */ + if (!got_pw && !(got_pw=fetch_ldap_pw(lp_ldap_admin_dn(), ldap_secret, sizeof(pstring)))) { - DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n")); + DEBUG(0, ("ldap_connect_system: Failed to retrieve password for %s from secrets.tdb\n", + lp_ldap_admin_dn())); return False; } - ldap_state->bind_dn = ldap_dn; - ldap_state->bind_secret = ldap_secret; - /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite (OpenLDAP) doesnt' seem to support it */ DEBUG(10,("ldap_connect_system: Binding to ldap server as \"%s\"\n", - ldap_dn)); - -#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) -# if LDAP_SET_REBIND_PROC_ARGS == 2 - ldap_set_rebind_proc(ldap_struct, &rebindproc_connect); -# endif -# if LDAP_SET_REBIND_PROC_ARGS == 3 - ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state); -# endif -#else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ -# if LDAP_SET_REBIND_PROC_ARGS == 2 - ldap_set_rebind_proc(ldap_struct, &rebindproc); -# endif -# if LDAP_SET_REBIND_PROC_ARGS == 3 - ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state); -# endif -#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ - - rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret); - - if (rc != LDAP_SUCCESS) { + lp_ldap_admin_dn())); + + if ((rc = ldap_simple_bind_s(ldap_struct, lp_ldap_admin_dn(), + ldap_secret)) != LDAP_SUCCESS) + { DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc))); return False; } @@ -423,19 +254,19 @@ static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * l /******************************************************************* run the search by name. ******************************************************************/ -static int ldapsam_search_one_user (struct ldapsam_privates *ldap_state, LDAP * ldap_struct, const char *filter, LDAPMessage ** result) +static int ldap_search_one_user (LDAP * ldap_struct, const char *filter, LDAPMessage ** result) { int scope = LDAP_SCOPE_SUBTREE; int rc; - DEBUG(2, ("ldapsam_search_one_user: searching for:[%s]\n", filter)); + DEBUG(2, ("ldap_search_one_user: searching for:[%s]\n", filter)); - rc = ldap_search_s(ldap_struct, lp_ldap_suffix (), scope, filter, (char **)attr, 0, result); + rc = ldap_search_s(ldap_struct, lp_ldap_suffix (), scope, (char*)filter, attribs, 0, result); if (rc != LDAP_SUCCESS) { - DEBUG(0,("ldapsam_search_one_user: Problem during the LDAP search: %s\n", + DEBUG(0,("ldap_search_one_user: Problem during the LDAP search: %s\n", ldap_err2string (rc))); - DEBUG(3,("ldapsam_search_one_user: Query was: %s, %s\n", lp_ldap_suffix(), + DEBUG(3,("ldap_search_one_user: Query was: %s, %s\n", lp_ldap_suffix(), filter)); } @@ -445,7 +276,7 @@ static int ldapsam_search_one_user (struct ldapsam_privates *ldap_state, LDAP * /******************************************************************* run the search by name. ******************************************************************/ -static int ldapsam_search_one_user_by_name (struct ldapsam_privates *ldap_state, LDAP * ldap_struct, const char *user, +static int ldap_search_one_user_by_name (LDAP * ldap_struct, const char *user, LDAPMessage ** result) { pstring filter; @@ -458,27 +289,26 @@ static int ldapsam_search_one_user_by_name (struct ldapsam_privates *ldap_state, /* * have to use this here because $ is filtered out - * in pstring_sub + * in pstring_sub */ all_string_sub(filter, "%u", user, sizeof(pstring)); - return ldapsam_search_one_user(ldap_state, ldap_struct, filter, result); + return ldap_search_one_user(ldap_struct, filter, result); } /******************************************************************* run the search by uid. ******************************************************************/ -static int ldapsam_search_one_user_by_uid(struct ldapsam_privates *ldap_state, - LDAP * ldap_struct, int uid, - LDAPMessage ** result) +static int ldap_search_one_user_by_uid(LDAP * ldap_struct, int uid, + LDAPMessage ** result) { struct passwd *user; pstring filter; /* Get the username from the system and look that up in the LDAP */ - if ((user = getpwuid_alloc(uid)) == NULL) { - DEBUG(3,("ldapsam_search_one_user_by_uid: Failed to locate uid [%d]\n", uid)); + if ((user = sys_getpwuid(uid)) == NULL) { + DEBUG(3,("ldap_search_one_user_by_uid: Failed to locate uid [%d]\n", uid)); return LDAP_NO_SUCH_OBJECT; } @@ -486,17 +316,14 @@ static int ldapsam_search_one_user_by_uid(struct ldapsam_privates *ldap_state, all_string_sub(filter, "%u", user->pw_name, sizeof(pstring)); - passwd_free(&user); - - return ldapsam_search_one_user(ldap_state, ldap_struct, filter, result); + return ldap_search_one_user(ldap_struct, filter, result); } /******************************************************************* run the search by rid. ******************************************************************/ -static int ldapsam_search_one_user_by_rid (struct ldapsam_privates *ldap_state, - LDAP * ldap_struct, uint32 rid, - LDAPMessage ** result) +static int ldap_search_one_user_by_rid (LDAP * ldap_struct, uint32 rid, + LDAPMessage ** result) { pstring filter; int rc; @@ -504,45 +331,43 @@ static int ldapsam_search_one_user_by_rid (struct ldapsam_privates *ldap_state, /* check if the user rid exsists, if not, try searching on the uid */ snprintf(filter, sizeof(filter) - 1, "rid=%i", rid); - rc = ldapsam_search_one_user(ldap_state, ldap_struct, filter, result); + rc = ldap_search_one_user(ldap_struct, filter, result); if (rc != LDAP_SUCCESS) - rc = ldapsam_search_one_user_by_uid(ldap_state, ldap_struct, - fallback_pdb_user_rid_to_uid(rid), - result); + rc = ldap_search_one_user_by_uid(ldap_struct, + pdb_user_rid_to_uid(rid), result); return rc; } /******************************************************************* -search an attribute and return the first value found. + search an attribute and return the first value found. + the string in 'value' is unchanged if the attribute does not exist ******************************************************************/ + static BOOL get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry, - char *attribute, pstring value) + char *attribute, char *value) { char **values; if ((values = ldap_get_values (ldap_struct, entry, attribute)) == NULL) { - value = NULL; - DEBUG (10, ("get_single_attribute: [%s] = [<does not exist>]\n", attribute)); - + DEBUG (2, ("get_single_attribute: [%s] = [<does not exist>]\n", attribute)); return False; } - + pstrcpy(value, values[0]); ldap_value_free(values); -#ifdef DEBUG_PASSWORDS - DEBUG (100, ("get_single_attribute: [%s] = [%s]\n", attribute, value)); -#endif + DEBUG (2, ("get_single_attribute: [%s] = [%s]\n", attribute, value)); + return True; } /************************************************************************ -Routine to manage the LDAPMod structure array -manage memory used by the array, by each struct, and values - + Routine to manage the LDAPMod structure array + manage memory used by the array, by each struct, and values ************************************************************************/ -static void make_a_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value) + +static void make_a_mod (LDAPMod *** modlist, int modop, char *attribute, char *value) { LDAPMod **mods; int i; @@ -617,11 +442,10 @@ static void make_a_mod (LDAPMod *** modlist, int modop, const char *attribute, c Initialize SAM_ACCOUNT from an LDAP query (Based on init_sam_from_buffer in pdb_tdb.c) *********************************************************************/ -static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, - SAM_ACCOUNT * sampass, - LDAP * ldap_struct, LDAPMessage * entry) +static BOOL init_sam_from_ldap (SAM_ACCOUNT * sampass, + LDAP * ldap_struct, LDAPMessage * entry) { - time_t logon_time, + time_t logon_time, logoff_time, kickoff_time, pass_last_set_time, @@ -638,17 +462,16 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, acct_desc, munged_dial, workstations; - struct passwd *pw; + struct passwd *sys_user; uint32 user_rid, group_rid; uint8 smblmpwd[16], smbntpwd[16]; uint16 acct_ctrl, logon_divs; - uint32 hours_len; + uint32 hours_len; uint8 hours[MAX_HOURS_LEN]; - pstring temp; - uid_t uid = -1; + pstring temp; gid_t gid = getegid(); @@ -668,224 +491,161 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, workstations[0] = '\0'; - if (sampass == NULL || ldap_struct == NULL || entry == NULL) { - DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n")); - return False; - } - get_single_attribute(ldap_struct, entry, "uid", username); DEBUG(2, ("Entry found for user: %s\n", username)); - + + pstrcpy(samlogon_user, username); + pstrcpy(nt_username, username); pstrcpy(domain, lp_workgroup()); - get_single_attribute(ldap_struct, entry, "rid", temp); - user_rid = (uint32)atol(temp); - - pdb_set_user_sid_from_rid(sampass, user_rid); - - if (!get_single_attribute(ldap_struct, entry, "primaryGroupID", temp)) { - group_rid = 0; - } else { - group_rid = (uint32)atol(temp); - pdb_set_group_sid_from_rid(sampass, group_rid); - } - - if ((ldap_state->permit_non_unix_accounts) - && (user_rid >= ldap_state->low_nua_rid) - && (user_rid <= ldap_state->high_nua_rid)) { - - } else { - - /* These values MAY be in LDAP, but they can also be retrieved through - * sys_getpw*() which is how we're doing it - */ + pass_last_set_time = TIME_T_MAX; + logon_time = TIME_T_MAX; + logoff_time = TIME_T_MAX; + kickoff_time = TIME_T_MAX; + pass_can_change_time = TIME_T_MAX; + pass_must_change_time = TIME_T_MAX; - pw = getpwnam_alloc(username); - if (pw == NULL) { - DEBUG (2,("init_sam_from_ldap: User [%s] does not exist via system getpwnam!\n", username)); - return False; - } - uid = pw->pw_uid; - gid = pw->pw_gid; - - pdb_set_unix_homedir(sampass, pw->pw_dir); - passwd_free(&pw); - - pdb_set_uid(sampass, uid); - pdb_set_gid(sampass, gid); - - if (group_rid == 0) { - GROUP_MAP map; - /* call the mapping code here */ - if(get_group_map_from_gid(gid, &map, MAPPING_WITHOUT_PRIV)) { - pdb_set_group_sid(sampass, &map.sid); - } - else { - pdb_set_group_sid_from_rid(sampass, pdb_gid_to_group_rid(gid)); - } - } - } - - if (!get_single_attribute(ldap_struct, entry, "pwdLastSet", temp)) { - /* leave as default */ - } else { + if (get_single_attribute(ldap_struct, entry, "pwdLastSet", temp)) pass_last_set_time = (time_t) atol(temp); - pdb_set_pass_last_set_time(sampass, pass_last_set_time); - } - if (!get_single_attribute(ldap_struct, entry, "logonTime", temp)) { - /* leave as default */ - } else { + if (get_single_attribute(ldap_struct, entry, "logonTime", temp)) logon_time = (time_t) atol(temp); - pdb_set_logon_time(sampass, logon_time, True); - } - if (!get_single_attribute(ldap_struct, entry, "logoffTime", temp)) { - /* leave as default */ - } else { + if (get_single_attribute(ldap_struct, entry, "logoffTime", temp)) logoff_time = (time_t) atol(temp); - pdb_set_logoff_time(sampass, logoff_time, True); - } - if (!get_single_attribute(ldap_struct, entry, "kickoffTime", temp)) { - /* leave as default */ - } else { + if (get_single_attribute(ldap_struct, entry, "kickoffTime", temp)) kickoff_time = (time_t) atol(temp); - pdb_set_kickoff_time(sampass, kickoff_time, True); - } - if (!get_single_attribute(ldap_struct, entry, "pwdCanChange", temp)) { - /* leave as default */ - } else { + if (get_single_attribute(ldap_struct, entry, "pwdCanChange", temp)) pass_can_change_time = (time_t) atol(temp); - pdb_set_pass_can_change_time(sampass, pass_can_change_time, True); - } - if (!get_single_attribute(ldap_struct, entry, "pwdMustChange", temp)) { - /* leave as default */ - } else { + if (get_single_attribute(ldap_struct, entry, "pwdMustChange", temp)) pass_must_change_time = (time_t) atol(temp); - pdb_set_pass_must_change_time(sampass, pass_must_change_time, True); - } /* recommend that 'gecos' and 'displayName' should refer to the same * attribute OID. userFullName depreciated, only used by Samba * primary rules of LDAP: don't make a new attribute when one is already defined * that fits your needs; using cn then displayName rather than 'userFullName' */ + + sam_logon_in_ssb = True; if (!get_single_attribute(ldap_struct, entry, "cn", fullname)) { - if (!get_single_attribute(ldap_struct, entry, "displayName", fullname)) { - /* leave as default */ - } else { - pdb_set_fullname(sampass, fullname); - } - } else { - pdb_set_fullname(sampass, fullname); + get_single_attribute(ldap_struct, entry, "displayName", fullname); } + if (!get_single_attribute(ldap_struct, entry, "homeDrive", dir_drive)) { - pdb_set_dir_drive(sampass, talloc_sub_specified(sampass->mem_ctx, - lp_logon_drive(), - username, domain, - uid, gid), - False); - } else { - pdb_set_dir_drive(sampass, dir_drive, True); + pstrcpy(dir_drive, lp_logon_drive()); + standard_sub_advanced(-1, username, "", gid, dir_drive, sizeof(dir_drive)); + DEBUG(5,("homeDrive fell back to %s\n",dir_drive)); + pdb_set_dir_drive(sampass, dir_drive, False); } + else + pdb_set_dir_drive(sampass, dir_drive, True); if (!get_single_attribute(ldap_struct, entry, "smbHome", homedir)) { - pdb_set_homedir(sampass, talloc_sub_specified(sampass->mem_ctx, - lp_logon_home(), - username, domain, - uid, gid), - False); - } else { - pdb_set_homedir(sampass, homedir, True); + pstrcpy(homedir, lp_logon_home()); + standard_sub_advanced(-1, username, "", gid, homedir, sizeof(homedir)); + DEBUG(5,("smbHome fell back to %s\n",homedir)); + pdb_set_homedir(sampass, homedir, False); } + else + pdb_set_homedir(sampass, homedir, True); if (!get_single_attribute(ldap_struct, entry, "scriptPath", logon_script)) { - pdb_set_logon_script(sampass, talloc_sub_specified(sampass->mem_ctx, - lp_logon_script(), - username, domain, - uid, gid), - False); - } else { - pdb_set_logon_script(sampass, logon_script, True); + pstrcpy(logon_script, lp_logon_script()); + standard_sub_advanced(-1, username, "", gid, logon_script, sizeof(logon_script)); + DEBUG(5,("scriptPath fell back to %s\n",logon_script)); + pdb_set_logon_script(sampass, logon_script, False); } + else + pdb_set_logon_script(sampass, logon_script, True); if (!get_single_attribute(ldap_struct, entry, "profilePath", profile_path)) { - pdb_set_profile_path(sampass, talloc_sub_specified(sampass->mem_ctx, - lp_logon_path(), - username, domain, - uid, gid), - False); - } else { - pdb_set_profile_path(sampass, profile_path, True); + pstrcpy(profile_path, lp_logon_path()); + standard_sub_advanced(-1, username, "", gid, profile_path, sizeof(profile_path)); + DEBUG(5,("profilePath fell back to %s\n",profile_path)); + pdb_set_profile_path(sampass, profile_path, False); } + else + pdb_set_profile_path(sampass, profile_path, True); + + sam_logon_in_ssb = False; - if (!get_single_attribute(ldap_struct, entry, "description", acct_desc)) { - /* leave as default */ - } else { - pdb_set_acct_desc(sampass, acct_desc); - } + get_single_attribute(ldap_struct, entry, "description", acct_desc); + get_single_attribute(ldap_struct, entry, "userWorkstations", workstations); + get_single_attribute(ldap_struct, entry, "rid", temp); + user_rid = (uint32)atol(temp); + get_single_attribute(ldap_struct, entry, "primaryGroupID", temp); + group_rid = (uint32)atol(temp); - if (!get_single_attribute(ldap_struct, entry, "userWorkstations", workstations)) { - /* leave as default */; - } else { - pdb_set_workstations(sampass, workstations); + + /* These values MAY be in LDAP, but they can also be retrieved through + * sys_getpw*() which is how we're doing it + */ + sys_user = sys_getpwnam(username); + if (sys_user == NULL) { + DEBUG (2,("init_sam_from_ldap: User [%s] does not ave a uid!\n", username)); + return False; } + /* FIXME: hours stuff should be cleaner */ logon_divs = 168; hours_len = 21; memset(hours, 0xff, hours_len); - if (!get_single_attribute (ldap_struct, entry, "lmPassword", temp)) { - /* leave as default */ - } else { - pdb_gethexpwd(temp, smblmpwd); - memset((char *)temp, '\0', strlen(temp)+1); - if (!pdb_set_lanman_passwd(sampass, smblmpwd)) - return False; - ZERO_STRUCT(smblmpwd); - } + get_single_attribute (ldap_struct, entry, "lmPassword", temp); + pdb_gethexpwd(temp, smblmpwd); + memset((char *)temp, '\0', sizeof(temp)); + get_single_attribute (ldap_struct, entry, "ntPassword", temp); + pdb_gethexpwd(temp, smbntpwd); + memset((char *)temp, '\0', sizeof(temp)); + get_single_attribute (ldap_struct, entry, "acctFlags", temp); + acct_ctrl = pdb_decode_acct_ctrl(temp); - if (!get_single_attribute (ldap_struct, entry, "ntPassword", temp)) { - /* leave as default */ - } else { - pdb_gethexpwd(temp, smbntpwd); - memset((char *)temp, '\0', strlen(temp)+1); - if (!pdb_set_nt_passwd(sampass, smbntpwd)) - return False; - ZERO_STRUCT(smbntpwd); - } - - if (!get_single_attribute (ldap_struct, entry, "acctFlags", temp)) { + if (acct_ctrl == 0) acct_ctrl |= ACB_NORMAL; - } else { - acct_ctrl = pdb_decode_acct_ctrl(temp); - if (acct_ctrl == 0) - acct_ctrl |= ACB_NORMAL; - pdb_set_acct_ctrl(sampass, acct_ctrl); - } + pdb_set_acct_ctrl(sampass, acct_ctrl); + pdb_set_logon_time(sampass, logon_time); + pdb_set_logoff_time(sampass, logoff_time); + pdb_set_kickoff_time(sampass, kickoff_time); + pdb_set_pass_can_change_time(sampass, pass_can_change_time); + pdb_set_pass_must_change_time(sampass, pass_must_change_time); + pdb_set_pass_last_set_time(sampass, pass_last_set_time); pdb_set_hours_len(sampass, hours_len); pdb_set_logon_divs(sampass, logon_divs); + pdb_set_uid(sampass, sys_user->pw_uid); + pdb_set_gid(sampass, sys_user->pw_gid); + pdb_set_user_rid(sampass, user_rid); + pdb_set_group_rid(sampass, group_rid); + pdb_set_username(sampass, username); pdb_set_domain(sampass, domain); pdb_set_nt_username(sampass, nt_username); + pdb_set_fullname(sampass, fullname); + + pdb_set_acct_desc(sampass, acct_desc); + pdb_set_workstations(sampass, workstations); pdb_set_munged_dial(sampass, munged_dial); + if (!pdb_set_nt_passwd(sampass, smbntpwd)) + return False; + if (!pdb_set_lanman_passwd(sampass, smblmpwd)) + return False; + /* pdb_set_unknown_3(sampass, unknown3); */ /* pdb_set_unknown_5(sampass, unknown5); */ /* pdb_set_unknown_6(sampass, unknown6); */ @@ -899,17 +659,9 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, Initialize SAM_ACCOUNT from an LDAP query (Based on init_buffer_from_sam in pdb_tdb.c) *********************************************************************/ -static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, - LDAPMod *** mods, int ldap_op, - const SAM_ACCOUNT * sampass) +static BOOL init_ldap_from_sam (LDAPMod *** mods, int ldap_state, SAM_ACCOUNT * sampass) { pstring temp; - uint32 rid; - - if (mods == NULL || sampass == NULL) { - DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n")); - return False; - } *mods = NULL; @@ -918,40 +670,27 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, * do this on a per-mod basis */ - make_a_mod(mods, ldap_op, "uid", pdb_get_username(sampass)); + + make_a_mod(mods, ldap_state, "uid", pdb_get_username(sampass)); DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass))); - if ( pdb_get_user_rid(sampass) ) { - rid = pdb_get_user_rid(sampass); - } else if (IS_SAM_SET(sampass, FLAG_SAM_UID)) { - rid = fallback_pdb_uid_to_user_rid(pdb_get_uid(sampass)); - } else if (ldap_state->permit_non_unix_accounts) { - rid = ldapsam_get_next_available_nua_rid(ldap_state); - if (rid == 0) { - DEBUG(0, ("NO user RID specified on account %s, and findining next available NUA RID failed, cannot store!\n", pdb_get_username(sampass))); - return False; - } - } else { - DEBUG(0, ("NO user RID specified on account %s, cannot store!\n", pdb_get_username(sampass))); - return False; - } + slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass)); + make_a_mod(mods, ldap_state, "pwdLastSet", temp); - slprintf(temp, sizeof(temp) - 1, "%i", rid); - make_a_mod(mods, ldap_op, "rid", temp); + slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass)); + make_a_mod(mods, ldap_state, "logonTime", temp); - if ( pdb_get_group_rid(sampass) ) { - rid = pdb_get_group_rid(sampass); - } else if (IS_SAM_SET(sampass, FLAG_SAM_GID)) { - rid = pdb_gid_to_group_rid(pdb_get_gid(sampass)); - } else if (ldap_state->permit_non_unix_accounts) { - rid = DOMAIN_GROUP_RID_USERS; - } else { - DEBUG(0, ("NO group RID specified on account %s, cannot store!\n", pdb_get_username(sampass))); - return False; - } + slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass)); + make_a_mod(mods, ldap_state, "logoffTime", temp); - slprintf(temp, sizeof(temp) - 1, "%i", rid); - make_a_mod(mods, ldap_op, "primaryGroupID", temp); + slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_kickoff_time(sampass)); + make_a_mod(mods, ldap_state, "kickoffTime", temp); + + slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass)); + make_a_mod(mods, ldap_state, "pwdCanChange", temp); + + slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_must_change_time(sampass)); + make_a_mod(mods, ldap_state, "pwdMustChange", temp); /* displayName, cn, and gecos should all be the same * most easily accomplished by giving them the same OID @@ -959,552 +698,268 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, * add-user script */ - make_a_mod(mods, ldap_op, "displayName", pdb_get_fullname(sampass)); - make_a_mod(mods, ldap_op, "cn", pdb_get_fullname(sampass)); - make_a_mod(mods, ldap_op, "description", pdb_get_acct_desc(sampass)); - make_a_mod(mods, ldap_op, "userWorkstations", pdb_get_workstations(sampass)); + make_a_mod(mods, ldap_state, "displayName", pdb_get_fullname(sampass)); + make_a_mod(mods, ldap_state, "cn", pdb_get_fullname(sampass)); + make_a_mod(mods, ldap_state, "description", pdb_get_acct_desc(sampass)); + make_a_mod(mods, ldap_state, "userWorkstations", pdb_get_workstations(sampass)); /* * Only updates fields which have been set (not defaults from smb.conf) */ - + if (IS_SAM_SET(sampass, FLAG_SAM_SMBHOME)) - make_a_mod(mods, ldap_op, "smbHome", pdb_get_homedir(sampass)); + make_a_mod(mods, ldap_state, "smbHome", pdb_get_homedir(sampass)); if (IS_SAM_SET(sampass, FLAG_SAM_DRIVE)) - make_a_mod(mods, ldap_op, "homeDrive", pdb_get_dir_drive(sampass)); - + make_a_mod(mods, ldap_state, "homeDrive", pdb_get_dirdrive(sampass)); + if (IS_SAM_SET(sampass, FLAG_SAM_LOGONSCRIPT)) - make_a_mod(mods, ldap_op, "scriptPath", pdb_get_logon_script(sampass)); + make_a_mod(mods, ldap_state, "scriptPath", pdb_get_logon_script(sampass)); if (IS_SAM_SET(sampass, FLAG_SAM_PROFILE)) - make_a_mod(mods, ldap_op, "profilePath", pdb_get_profile_path(sampass)); - - if (IS_SAM_SET(sampass, FLAG_SAM_LOGONTIME)) { - slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass)); - make_a_mod(mods, ldap_op, "logonTime", temp); - } - - if (IS_SAM_SET(sampass, FLAG_SAM_LOGOFFTIME)) { - slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass)); - make_a_mod(mods, ldap_op, "logoffTime", temp); - } - - if (IS_SAM_SET(sampass, FLAG_SAM_KICKOFFTIME)) { - slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_kickoff_time(sampass)); - make_a_mod(mods, ldap_op, "kickoffTime", temp); - } - - - if (IS_SAM_SET(sampass, FLAG_SAM_CANCHANGETIME)) { - slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass)); - make_a_mod(mods, ldap_op, "pwdCanChange", temp); - } + make_a_mod(mods, ldap_state, "profilePath", pdb_get_profile_path(sampass)); + - if (IS_SAM_SET(sampass, FLAG_SAM_MUSTCHANGETIME)) { - slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_must_change_time(sampass)); - make_a_mod(mods, ldap_op, "pwdMustChange", temp); - } + if ( !pdb_get_user_rid(sampass)) + slprintf(temp, sizeof(temp) - 1, "%i", pdb_uid_to_user_rid(pdb_get_uid(sampass))); + else + slprintf(temp, sizeof(temp) - 1, "%i", pdb_get_user_rid(sampass)); + make_a_mod(mods, ldap_state, "rid", temp); - if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))|| - (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) { + if ( !pdb_get_group_rid(sampass)) + slprintf(temp, sizeof(temp) - 1, "%i", pdb_gid_to_group_rid(pdb_get_gid(sampass))); + else + slprintf(temp, sizeof(temp) - 1, "%i", pdb_get_group_rid(sampass)); + make_a_mod(mods, ldap_state, "primaryGroupID", temp); - pdb_sethexpwd (temp, pdb_get_lanman_passwd(sampass), pdb_get_acct_ctrl(sampass)); - make_a_mod (mods, ldap_op, "lmPassword", temp); + /* FIXME: Hours stuff goes in LDAP */ + pdb_sethexpwd (temp, pdb_get_lanman_passwd(sampass), pdb_get_acct_ctrl(sampass)); + make_a_mod (mods, ldap_state, "lmPassword", temp); - pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass), pdb_get_acct_ctrl(sampass)); - make_a_mod (mods, ldap_op, "ntPassword", temp); + pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass), pdb_get_acct_ctrl(sampass)); + make_a_mod (mods, ldap_state, "ntPassword", temp); - slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass)); - make_a_mod(mods, ldap_op, "pwdLastSet", temp); - - } - - /* FIXME: Hours stuff goes in LDAP */ - - make_a_mod (mods, ldap_op, "acctFlags", pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), + make_a_mod (mods, ldap_state, "acctFlags", pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), NEW_PW_FORMAT_SPACE_PADDED_LEN)); return True; } - -/********************************************************************** -Connect to LDAP server and find the next available RID. -*********************************************************************/ -static uint32 check_nua_rid_is_avail(struct ldapsam_privates *ldap_state, uint32 top_rid, LDAP *ldap_struct) -{ - LDAPMessage *result; - uint32 final_rid = (top_rid & (~USER_RID_TYPE)) + RID_MULTIPLIER; - if (top_rid == 0) { - return 0; - } - - if (final_rid < ldap_state->low_nua_rid || final_rid > ldap_state->high_nua_rid) { - return 0; - } - - if (ldapsam_search_one_user_by_rid(ldap_state, ldap_struct, final_rid, &result) != LDAP_SUCCESS) { - DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the confirmation search failed!\n", final_rid, final_rid)); - ldap_msgfree(result); - return 0; - } - - if (ldap_count_entries(ldap_struct, result) != 0) { - DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the RID is already in use!!\n", final_rid, final_rid)); - ldap_msgfree(result); - return 0; - } - - DEBUG(5, ("NUA RID %d (0x%x), declared valid\n", final_rid, final_rid)); - ldap_msgfree(result); - return final_rid; -} - -/********************************************************************** -Extract the RID from an LDAP entry -*********************************************************************/ -static uint32 entry_to_user_rid(struct ldapsam_privates *ldap_state, LDAPMessage *entry, LDAP *ldap_struct) { - uint32 rid; - SAM_ACCOUNT *user = NULL; - if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) { - return 0; - } - - if (init_sam_from_ldap(ldap_state, user, ldap_struct, entry)) { - rid = pdb_get_user_rid(user); - } else { - rid =0; - } - pdb_free_sam(&user); - if (rid >= ldap_state->low_nua_rid && rid <= ldap_state->high_nua_rid) { - return rid; - } - return 0; -} - - -/********************************************************************** -Connect to LDAP server and find the next available RID. -*********************************************************************/ -static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state, LDAP *ldap_struct) -{ - int rc; - pstring filter; - LDAPMessage *result; - LDAPMessage *entry; - char *final_filter = NULL; - uint32 top_rid = 0; - uint32 count; - uint32 rid; - - pstrcpy(filter, lp_ldap_filter()); - all_string_sub(filter, "%u", "*", sizeof(pstring)); - -#if 0 - asprintf(&final_filter, "(&(%s)(&(rid>=%d)(rid<=%d)))", filter, ldap_state->low_nua_rid, ldap_state->high_nua_rid); -#else - final_filter = strdup(filter); -#endif - DEBUG(2, ("ldapsam_get_next_available_nua_rid: searching for:[%s]\n", final_filter)); - - rc = ldap_search_s(ldap_struct, lp_ldap_suffix(), - LDAP_SCOPE_SUBTREE, final_filter, (char **)attr, 0, - &result); - - if (rc != LDAP_SUCCESS) { - DEBUG(3, ("LDAP search failed! cannot find base for NUA RIDs: %s\n", ldap_err2string(rc))); - DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter)); - - free(final_filter); - ldap_msgfree(result); - result = NULL; - return 0; - } - - count = ldap_count_entries(ldap_struct, result); - DEBUG(2, ("search_top_nua_rid: %d entries in the base!\n", count)); - - if (count == 0) { - DEBUG(3, ("LDAP search returned no records, assuming no non-unix-accounts present!: %s\n", ldap_err2string(rc))); - DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter)); - free(final_filter); - ldap_msgfree(result); - result = NULL; - return ldap_state->low_nua_rid; - } - - free(final_filter); - entry = ldap_first_entry(ldap_struct,result); - - top_rid = entry_to_user_rid(ldap_state, entry, ldap_struct); - - while ((entry = ldap_next_entry(ldap_struct, entry))) { - - rid = entry_to_user_rid(ldap_state, entry, ldap_struct); - if (rid > top_rid) { - top_rid = rid; - } - } - - ldap_msgfree(result); - - if (top_rid < ldap_state->low_nua_rid) - top_rid = ldap_state->low_nua_rid; - - return top_rid; -} - -/********************************************************************** -Connect to LDAP server and find the next available RID. -*********************************************************************/ -static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state) { - LDAP *ldap_struct; - uint32 next_nua_rid; - uint32 top_nua_rid; - - if (!ldapsam_open_connection(ldap_state, &ldap_struct)) { - return 0; - } - if (!ldapsam_connect_system(ldap_state, ldap_struct)) { - ldap_unbind(ldap_struct); - return 0; - } - - top_nua_rid = search_top_nua_rid(ldap_state, ldap_struct); - - next_nua_rid = check_nua_rid_is_avail(ldap_state, - top_nua_rid, ldap_struct); - - ldap_unbind(ldap_struct); - return next_nua_rid; -} - /********************************************************************** Connect to LDAP server for password enumeration *********************************************************************/ -static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update) +BOOL pdb_setsampwent(BOOL update) { - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; int rc; pstring filter; - if (!ldapsam_open_connection(ldap_state, &ldap_state->ldap_struct)) { - return ret; + if (!ldap_open_connection(&global_ldap_ent.ldap_struct)) + { + return False; } - if (!ldapsam_connect_system(ldap_state, ldap_state->ldap_struct)) { - ldap_unbind(ldap_state->ldap_struct); - return ret; + if (!ldap_connect_system(global_ldap_ent.ldap_struct)) + { + ldap_unbind(global_ldap_ent.ldap_struct); + return False; } pstrcpy(filter, lp_ldap_filter()); all_string_sub(filter, "%u", "*", sizeof(pstring)); - rc = ldap_search_s(ldap_state->ldap_struct, lp_ldap_suffix(), - LDAP_SCOPE_SUBTREE, filter, (char **)attr, 0, - &ldap_state->result); + rc = ldap_search_s(global_ldap_ent.ldap_struct, lp_ldap_suffix(), + LDAP_SCOPE_SUBTREE, filter, attribs, 0, + &global_ldap_ent.result); - if (rc != LDAP_SUCCESS) { + if (rc != LDAP_SUCCESS) + { DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc))); DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter)); - ldap_msgfree(ldap_state->result); - ldap_unbind(ldap_state->ldap_struct); - ldap_state->ldap_struct = NULL; - ldap_state->result = NULL; - return ret; + ldap_msgfree(global_ldap_ent.result); + ldap_unbind(global_ldap_ent.ldap_struct); + global_ldap_ent.ldap_struct = NULL; + global_ldap_ent.result = NULL; + return False; } - DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n", - ldap_count_entries(ldap_state->ldap_struct, - ldap_state->result))); + DEBUG(2, ("pdb_setsampwent: %d entries in the base!\n", + ldap_count_entries(global_ldap_ent.ldap_struct, + global_ldap_ent.result))); - ldap_state->entry = ldap_first_entry(ldap_state->ldap_struct, - ldap_state->result); - ldap_state->index = 0; + global_ldap_ent.entry = ldap_first_entry(global_ldap_ent.ldap_struct, + global_ldap_ent.result); + global_ldap_ent.index = -1; - return NT_STATUS_OK; + return True; } /********************************************************************** End enumeration of the LDAP password list *********************************************************************/ -static void ldapsam_endsampwent(struct pdb_methods *my_methods) +void pdb_endsampwent(void) { - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; - if (ldap_state->ldap_struct && ldap_state->result) { - ldap_msgfree(ldap_state->result); - ldap_unbind(ldap_state->ldap_struct); - ldap_state->ldap_struct = NULL; - ldap_state->result = NULL; + if (global_ldap_ent.ldap_struct && global_ldap_ent.result) + { + ldap_msgfree(global_ldap_ent.result); + ldap_unbind(global_ldap_ent.ldap_struct); + global_ldap_ent.ldap_struct = NULL; + global_ldap_ent.result = NULL; } } /********************************************************************** Get the next entry in the LDAP password database *********************************************************************/ -static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user) +BOOL pdb_getsampwent(SAM_ACCOUNT * user) { - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; - BOOL bret = False; - - /* The rebind proc needs this *HACK*. We are not multithreaded, so - this will work, but it's not nice. */ - static_ldap_state = ldap_state; + if (!global_ldap_ent.entry) + return False; - while (!bret) { - if (!ldap_state->entry) - return ret; - - ldap_state->index++; - bret = init_sam_from_ldap(ldap_state, user, ldap_state->ldap_struct, - ldap_state->entry); - - ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct, - ldap_state->entry); + global_ldap_ent.index++; + if (global_ldap_ent.index > 0) + { + global_ldap_ent.entry = ldap_next_entry(global_ldap_ent.ldap_struct, global_ldap_ent.entry); } - return NT_STATUS_OK; + if (global_ldap_ent.entry != NULL) + { + return init_sam_from_ldap(user, global_ldap_ent.ldap_struct, + global_ldap_ent.entry); + } + return False; } /********************************************************************** Get SAM_ACCOUNT entry from LDAP by username *********************************************************************/ -static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname) +BOOL pdb_getsampwnam(SAM_ACCOUNT * user, char *sname) { - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; LDAP *ldap_struct; LDAPMessage *result; LDAPMessage *entry; - if (!ldapsam_open_connection(ldap_state, &ldap_struct)) - return ret; - if (!ldapsam_connect_system(ldap_state, ldap_struct)) { + if (!ldap_open_connection(&ldap_struct)) + return False; + if (!ldap_connect_system(ldap_struct)) + { ldap_unbind(ldap_struct); - return ret; + return False; } - if (ldapsam_search_one_user_by_name(ldap_state, ldap_struct, sname, &result) != LDAP_SUCCESS) { + if (ldap_search_one_user_by_name(ldap_struct, sname, &result) != LDAP_SUCCESS) + { ldap_unbind(ldap_struct); - return ret; + return False; } - if (ldap_count_entries(ldap_struct, result) < 1) { - DEBUG(4, - ("We don't find this user [%s] count=%d\n", sname, + if (ldap_count_entries(ldap_struct, result) < 1) + { + pstring filter; + + pstrcpy(filter, lp_ldap_filter()); + standard_sub_advanced(-1, sname, "", -1, filter, sizeof(filter)); + DEBUG(0,("LDAP search \"%s\" returned %d entries.\n", filter, ldap_count_entries(ldap_struct, result))); ldap_unbind(ldap_struct); - return ret; + return False; } entry = ldap_first_entry(ldap_struct, result); - if (entry) { - if (!init_sam_from_ldap(ldap_state, user, ldap_struct, entry)) { - DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname)); - ldap_msgfree(result); - ldap_unbind(ldap_struct); - return ret; - } + if (entry) + { + init_sam_from_ldap(user, ldap_struct, entry); ldap_msgfree(result); ldap_unbind(ldap_struct); - ret = NT_STATUS_OK; - } else { + return True; + } + else + { ldap_msgfree(result); ldap_unbind(ldap_struct); + return False; } - return ret; } /********************************************************************** Get SAM_ACCOUNT entry from LDAP by rid *********************************************************************/ -static NTSTATUS ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *user, uint32 rid) +BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid) { - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; LDAP *ldap_struct; LDAPMessage *result; LDAPMessage *entry; - if (!ldapsam_open_connection(ldap_state, &ldap_struct)) - return ret; + if (!ldap_open_connection(&ldap_struct)) + return False; - if (!ldapsam_connect_system(ldap_state, ldap_struct)) { + if (!ldap_connect_system(ldap_struct)) + { ldap_unbind(ldap_struct); - return ret; + return False; } - if (ldapsam_search_one_user_by_rid(ldap_state, ldap_struct, rid, &result) != LDAP_SUCCESS) { + if (ldap_search_one_user_by_rid(ldap_struct, rid, &result) != + LDAP_SUCCESS) + { ldap_unbind(ldap_struct); - return ret; + return False; } - if (ldap_count_entries(ldap_struct, result) < 1) { - DEBUG(4, + if (ldap_count_entries(ldap_struct, result) < 1) + { + DEBUG(0, ("We don't find this rid [%i] count=%d\n", rid, ldap_count_entries(ldap_struct, result))); ldap_unbind(ldap_struct); - return ret; + return False; } entry = ldap_first_entry(ldap_struct, result); - if (entry) { - if (!init_sam_from_ldap(ldap_state, user, ldap_struct, entry)) { - DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n")); - ldap_msgfree(result); - ldap_unbind(ldap_struct); - return ret; - } - ldap_msgfree(result); - ldap_unbind(ldap_struct); - ret = NT_STATUS_OK; - } else { + if (entry) + { + init_sam_from_ldap(user, ldap_struct, entry); ldap_msgfree(result); ldap_unbind(ldap_struct); + return True; } - return ret; -} - -static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid) -{ - uint32 rid; - if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) - return NT_STATUS_UNSUCCESSFUL; - return ldapsam_getsampwrid(my_methods, user, rid); -} - -static NTSTATUS ldapsam_modify_entry(LDAP *ldap_struct,SAM_ACCOUNT *newpwd,char *dn,LDAPMod **mods,int ldap_op) -{ - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - int version; - int rc; - - switch(ldap_op) + else { - case LDAP_MOD_ADD: - make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "account"); - if((rc = ldap_add_s(ldap_struct,dn,mods))!=LDAP_SUCCESS) { - char *ld_error; - ldap_get_option(ldap_struct, LDAP_OPT_ERROR_STRING, - &ld_error); - DEBUG(0, - ("failed to add user with uid = %s with: %s\n\t%s\n", - pdb_get_username(newpwd), ldap_err2string(rc), - ld_error)); - free(ld_error); - return ret; - } - break; - case LDAP_MOD_REPLACE: - if((rc = ldap_modify_s(ldap_struct,dn,mods))!=LDAP_SUCCESS) { - char *ld_error; - ldap_get_option(ldap_struct, LDAP_OPT_ERROR_STRING, - &ld_error); - DEBUG(0, - ("failed to modify user with uid = %s with: %s\n\t%s\n", - pdb_get_username(newpwd), ldap_err2string(rc), - ld_error)); - free(ld_error); - return ret; - } - break; - default: - DEBUG(0,("Wrong LDAP operation type: %d!\n",ldap_op)); - return ret; - } - -#ifdef LDAP_EXOP_X_MODIFY_PASSWD - if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))&& - (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_OFF)&& - (pdb_get_plaintext_passwd(newpwd)!=NULL)) { - BerElement *ber; - struct berval *bv; - char *retoid; - struct berval *retdata; - - if (ldap_get_option(ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) { - if (version != LDAP_VERSION3) { - version = LDAP_VERSION3; - ldap_set_option (ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version); - } - } - - if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) { - DEBUG(0,("ber_alloc_t returns NULL\n")); - return ret; - } - ber_printf (ber, "{"); - ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID,dn); - ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, pdb_get_plaintext_passwd(newpwd)); - ber_printf (ber, "N}"); - - if ((rc = ber_flatten (ber, &bv))<0) { - DEBUG(0,("ber_flatten returns a value <0\n")); - return ret; - } - - ber_free(ber,1); - - if ((rc = ldap_extended_operation_s(ldap_struct, LDAP_EXOP_X_MODIFY_PASSWD, - bv, NULL, NULL, &retoid, &retdata))!=LDAP_SUCCESS) { - DEBUG(0,("LDAP Password could not be changed for user %s: %s\n", - pdb_get_username(newpwd),ldap_err2string(rc))); - } else { - DEBUG(3,("LDAP Password changed for user %s\n",pdb_get_username(newpwd))); - - ber_bvfree(retdata); - ber_memfree(retoid); - } - ber_bvfree(bv); + ldap_msgfree(result); + ldap_unbind(ldap_struct); + return False; } -#else - DEBUG(10,("LDAP PASSWORD SYNC is not supported!\n")); -#endif /* LDAP_EXOP_X_MODIFY_PASSWD */ - return NT_STATUS_OK; } /********************************************************************** Delete entry from LDAP for username *********************************************************************/ -static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct) + +BOOL pdb_delete_sam_account(char *sname) { - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; - const char *sname; int rc; char *dn; LDAP *ldap_struct; LDAPMessage *entry; LDAPMessage *result; - if (!sam_acct) { - DEBUG(0, ("sam_acct was NULL!\n")); - return ret; - } - - sname = pdb_get_username(sam_acct); - - if (!ldapsam_open_connection(ldap_state, &ldap_struct)) - return ret; + /* Ensure we have euid as root - else deny this. */ + if (!ldap_open_connection (&ldap_struct)) + return False; DEBUG (3, ("Deleting user %s from LDAP.\n", sname)); - if (!ldapsam_connect_system(ldap_state, ldap_struct)) { + if (!ldap_connect_system (ldap_struct)) { ldap_unbind (ldap_struct); DEBUG(0, ("Failed to delete user %s from LDAP.\n", sname)); - return ret; + return False; } - rc = ldapsam_search_one_user_by_name(ldap_state, ldap_struct, sname, &result); + rc = ldap_search_one_user_by_name (ldap_struct, sname, &result); if (ldap_count_entries (ldap_struct, result) == 0) { DEBUG (0, ("User doesn't exit!\n")); ldap_msgfree (result); ldap_unbind (ldap_struct); - return ret; + return False; } entry = ldap_first_entry (ldap_struct, result); dn = ldap_get_dn (ldap_struct, entry); - ldap_msgfree(result); - + rc = ldap_delete_s (ldap_struct, dn); ldap_memfree (dn); @@ -1515,21 +970,20 @@ static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_A sname, ldap_err2string (rc), ld_error)); free (ld_error); ldap_unbind (ldap_struct); - return ret; + return False; } DEBUG (2,("successfully deleted uid = %s from the LDAP database\n", sname)); ldap_unbind (ldap_struct); - return NT_STATUS_OK; + return True; } /********************************************************************** Update SAM_ACCOUNT *********************************************************************/ -static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd) + +BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd, BOOL override) { - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; int rc; char *dn; LDAP *ldap_struct; @@ -1537,100 +991,91 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_A LDAPMessage *entry; LDAPMod **mods; - if (!ldapsam_open_connection(ldap_state, &ldap_struct)) /* open a connection to the server */ - return ret; + if (!ldap_open_connection(&ldap_struct)) /* open a connection to the server */ + return False; - if (!ldapsam_connect_system(ldap_state, ldap_struct)) { /* connect as system account */ + if (!ldap_connect_system(ldap_struct)) /* connect as system account */ { ldap_unbind(ldap_struct); - return ret; + return False; } - rc = ldapsam_search_one_user_by_name(ldap_state, ldap_struct, - pdb_get_username(newpwd), &result); + rc = ldap_search_one_user_by_name(ldap_struct, + pdb_get_username(newpwd), &result); if (ldap_count_entries(ldap_struct, result) == 0) { DEBUG(0, ("No user to modify!\n")); ldap_msgfree(result); ldap_unbind(ldap_struct); - return ret; + return False; } - if (!init_ldap_from_sam(ldap_state, &mods, LDAP_MOD_REPLACE, newpwd)) { - DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n")); - ldap_msgfree(result); - ldap_unbind(ldap_struct); - return ret; - } + init_ldap_from_sam(&mods, LDAP_MOD_REPLACE, newpwd); entry = ldap_first_entry(ldap_struct, result); dn = ldap_get_dn(ldap_struct, entry); - ldap_msgfree(result); - - if (NT_STATUS_IS_ERR(ldapsam_modify_entry(ldap_struct,newpwd,dn,mods,LDAP_MOD_REPLACE))) { - DEBUG(0,("failed to modify user with uid = %s\n", - pdb_get_username(newpwd))); - ldap_mods_free(mods,1); + + rc = ldap_modify_s(ldap_struct, dn, mods); + + if (rc != LDAP_SUCCESS) { + char *ld_error; + ldap_get_option(ldap_struct, LDAP_OPT_ERROR_STRING, + &ld_error); + DEBUG(0, + ("failed to modify user with uid = %s with: %s\n\t%s\n", + pdb_get_username(newpwd), ldap_err2string(rc), + ld_error)); + free(ld_error); ldap_unbind(ldap_struct); - return ret; + return False; } - - DEBUG(2, - ("successfully modified uid = %s in the LDAP database\n", + DEBUG(2, ("successfully modified uid = %s in the LDAP database\n", pdb_get_username(newpwd))); ldap_mods_free(mods, 1); ldap_unbind(ldap_struct); - return NT_STATUS_OK; + return True; } /********************************************************************** Add SAM_ACCOUNT to LDAP *********************************************************************/ -static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd) + +BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd) { - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; - int rc; - pstring filter; - LDAP *ldap_struct = NULL; - LDAPMessage *result = NULL; - pstring dn; - LDAPMod **mods = NULL; + int rc; + pstring filter; + LDAP *ldap_struct; + LDAPMessage *result; + pstring dn; + LDAPMod **mods; int ldap_op; uint32 num_result; - - const char *username = pdb_get_username(newpwd); - if (!username || !*username) { - DEBUG(0, ("Cannot add user without a username!\n")); - return ret; - } - if (!ldapsam_open_connection(ldap_state, &ldap_struct)) /* open a connection to the server */ - return ret; + if (!ldap_open_connection(&ldap_struct)) /* open a connection to the server */ + return False; - if (!ldapsam_connect_system(ldap_state, ldap_struct)) { /* connect as system account */ + if (!ldap_connect_system(ldap_struct)) /* connect as system account */ { ldap_unbind(ldap_struct); - return ret; + return False; } - rc = ldapsam_search_one_user_by_name (ldap_state, ldap_struct, username, &result); + rc = ldap_search_one_user_by_name (ldap_struct, pdb_get_username(newpwd), &result); if (ldap_count_entries(ldap_struct, result) != 0) { DEBUG(0,("User already in the base, with samba properties\n")); ldap_msgfree(result); ldap_unbind(ldap_struct); - return ret; + return False; } ldap_msgfree(result); - slprintf (filter, sizeof (filter) - 1, "uid=%s", username); - rc = ldapsam_search_one_user(ldap_state, ldap_struct, filter, &result); + slprintf (filter, sizeof (filter) - 1, "uid=%s", pdb_get_username(newpwd)); + rc = ldap_search_one_user(ldap_struct, filter, &result); num_result = ldap_count_entries(ldap_struct, result); if (num_result > 1) { DEBUG (0, ("More than one user with that uid exists: bailing out!\n")); - ldap_msgfree(result); - return ret; + return False; } /* Check if we need to update an existing entry */ @@ -1648,156 +1093,43 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO /* Check if we need to add an entry */ DEBUG(3,("Adding new user\n")); ldap_op = LDAP_MOD_ADD; - if (username[strlen(username)-1] == '$') { - slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_machine_suffix ()); - } else { - slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_user_suffix ()); - } + slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", pdb_get_username(newpwd), lp_ldap_suffix ()); } ldap_msgfree(result); - if (!init_ldap_from_sam(ldap_state, &mods, ldap_op, newpwd)) { - DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n")); - ldap_mods_free(mods, 1); - ldap_unbind(ldap_struct); - return ret; - } + init_ldap_from_sam(&mods, ldap_op, newpwd); make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "sambaAccount"); - if (NT_STATUS_IS_ERR(ldapsam_modify_entry(ldap_struct,newpwd,dn,mods,ldap_op))) { - DEBUG(0,("failed to modify/add user with uid = %s (dn = %s)\n", - pdb_get_username(newpwd),dn)); - ldap_mods_free(mods,1); - ldap_unbind(ldap_struct); - return ret; - } - - DEBUG(2,("added: uid = %s in the LDAP database\n", pdb_get_username(newpwd))); - ldap_mods_free(mods, 1); - ldap_unbind(ldap_struct); - return NT_STATUS_OK; -} - -static void free_private_data(void **vp) -{ - struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp; - - if ((*ldap_state)->ldap_struct) { - ldap_unbind((*ldap_state)->ldap_struct); - } - - if ((*ldap_state)->bind_secret) { - memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret)); - } - - SAFE_FREE((*ldap_state)->bind_dn); - SAFE_FREE((*ldap_state)->bind_secret); - - *ldap_state = NULL; - - /* No need to free any further, as it is talloc()ed */ -} - -NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) -{ - NTSTATUS nt_status; - struct ldapsam_privates *ldap_state; - - if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) { - return nt_status; - } - - (*pdb_method)->name = "ldapsam"; - - (*pdb_method)->setsampwent = ldapsam_setsampwent; - (*pdb_method)->endsampwent = ldapsam_endsampwent; - (*pdb_method)->getsampwent = ldapsam_getsampwent; - (*pdb_method)->getsampwnam = ldapsam_getsampwnam; - (*pdb_method)->getsampwsid = ldapsam_getsampwsid; - (*pdb_method)->add_sam_account = ldapsam_add_sam_account; - (*pdb_method)->update_sam_account = ldapsam_update_sam_account; - (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account; - - /* TODO: Setup private data and free */ - - ldap_state = talloc_zero(pdb_context->mem_ctx, sizeof(struct ldapsam_privates)); - - if (!ldap_state) { - DEBUG(0, ("talloc() failed for ldapsam private_data!\n")); - return NT_STATUS_NO_MEMORY; - } - - if (location) { - ldap_state->uri = talloc_strdup(pdb_context->mem_ctx, location); -#ifdef WITH_LDAP_SAMCONFIG + if (ldap_op == LDAP_MOD_REPLACE) { + rc = ldap_modify_s(ldap_struct, dn, mods); } else { - int ldap_port = lp_ldap_port(); - - /* remap default port is no SSL */ - if ( (lp_ldap_ssl() == LDAP_SSL_OFF) && (ldap_port == 636) ) { - ldap_port = 389; - } - - ldap_state->uri = talloc_asprintf(pdb_context->mem_ctx, "%s://%s:%d", lp_ldap_ssl() ? "ldap" : "ldaps", lp_ldap_server(), ldap_port); - if (!ldap_state->uri) { - return NT_STATUS_NO_MEMORY; - } -#else - } else { - ldap_state->uri = "ldaps://localhost"; -#endif + make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "account"); + rc = ldap_add_s(ldap_struct, dn, mods); } - (*pdb_method)->private_data = ldap_state; - - (*pdb_method)->free_private_data = free_private_data; - - return NT_STATUS_OK; -} - -NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) -{ - NTSTATUS nt_status; - struct ldapsam_privates *ldap_state; - uint32 low_nua_uid, high_nua_uid; + if (rc != LDAP_SUCCESS) { + char *ld_error; - if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam(pdb_context, pdb_method, location))) { - return nt_status; + ldap_get_option (ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); + DEBUG(0,("failed to modify user with uid = %s with: %s\n\t%s\n", + pdb_get_username(newpwd), ldap_err2string (rc), ld_error)); + free(ld_error); + ldap_mods_free(mods, 1); + ldap_unbind(ldap_struct); + return False; } - - (*pdb_method)->name = "ldapsam_nua"; - - ldap_state = (*pdb_method)->private_data; - ldap_state->permit_non_unix_accounts = True; - - if (!lp_non_unix_account_range(&low_nua_uid, &high_nua_uid)) { - DEBUG(0, ("cannot use ldapsam_nua without 'non unix account range' in smb.conf!\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - ldap_state->low_nua_rid=fallback_pdb_uid_to_user_rid(low_nua_uid); - - ldap_state->high_nua_rid=fallback_pdb_uid_to_user_rid(high_nua_uid); - - return NT_STATUS_OK; + DEBUG(2,("added: uid = %s in the LDAP database\n", pdb_get_username(newpwd))); + ldap_mods_free(mods, 1); + ldap_unbind(ldap_struct); + return True; } - #else - -NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) -{ - DEBUG(0, ("ldap not detected at configure time, ldapsam not availalble!\n")); - return NT_STATUS_UNSUCCESSFUL; -} - -NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) +void dummy_function(void); +void +dummy_function (void) { - DEBUG(0, ("ldap not dectected at configure time, ldapsam_nua not available!\n")); - return NT_STATUS_UNSUCCESSFUL; -} - - +} /* stop some compilers complaining */ #endif |