diff options
Diffstat (limited to 'source/passdb')
-rw-r--r-- | source/passdb/passdb.c | 26 | ||||
-rw-r--r-- | source/passdb/pdb_get_set.c | 18 | ||||
-rw-r--r-- | source/passdb/pdb_interface.c | 12 | ||||
-rw-r--r-- | source/passdb/pdb_ldap.c | 115 | ||||
-rw-r--r-- | source/passdb/pdb_mysql.c | 5 | ||||
-rw-r--r-- | source/passdb/pdb_pgsql.c | 2 | ||||
-rw-r--r-- | source/passdb/pdb_smbpasswd.c | 2 | ||||
-rw-r--r-- | source/passdb/pdb_sql.c | 8 | ||||
-rw-r--r-- | source/passdb/pdb_tdb.c | 17 | ||||
-rw-r--r-- | source/passdb/pdb_xml.c | 2 | ||||
-rw-r--r-- | source/passdb/privileges.c | 341 | ||||
-rw-r--r-- | source/passdb/util_sam_sid.c | 24 |
12 files changed, 88 insertions, 484 deletions
diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c index aeea4316f38..1f5e4be6cf6 100644 --- a/source/passdb/passdb.c +++ b/source/passdb/passdb.c @@ -1777,6 +1777,7 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen; uint32 pwHistLen = 0; BOOL ret = True; + fstring tmpstring; if(sampass == NULL || buf == NULL) { DEBUG(0, ("init_sam_from_buffer_v2: NULL parameters found!\n")); @@ -1840,7 +1841,9 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) pdb_set_fullname(sampass, fullname, PDB_SET); if (homedir) { - pdb_set_homedir(sampass, homedir, PDB_SET); + fstrcpy( tmpstring, homedir ); + standard_sub_basic( username, tmpstring, sizeof(tmpstring) ); + pdb_set_homedir(sampass, tmpstring, PDB_SET); } else { pdb_set_homedir(sampass, @@ -1850,14 +1853,14 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) if (dir_drive) pdb_set_dir_drive(sampass, dir_drive, PDB_SET); - else { - pdb_set_dir_drive(sampass, - talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()), - PDB_DEFAULT); - } + else + pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT ); - if (logon_script) - pdb_set_logon_script(sampass, logon_script, PDB_SET); + if (logon_script) { + fstrcpy( tmpstring, logon_script ); + standard_sub_basic( username, tmpstring, sizeof(tmpstring) ); + pdb_set_logon_script(sampass, tmpstring, PDB_SET); + } else { pdb_set_logon_script(sampass, talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()), @@ -1865,8 +1868,11 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) } if (profile_path) { - pdb_set_profile_path(sampass, profile_path, PDB_SET); - } else { + fstrcpy( tmpstring, profile_path ); + standard_sub_basic( username, tmpstring, sizeof(tmpstring) ); + pdb_set_profile_path(sampass, tmpstring, PDB_SET); + } + else { pdb_set_profile_path(sampass, talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()), PDB_DEFAULT); diff --git a/source/passdb/pdb_get_set.c b/source/passdb/pdb_get_set.c index 2ca76384721..92e2cee7100 100644 --- a/source/passdb/pdb_get_set.c +++ b/source/passdb/pdb_get_set.c @@ -327,14 +327,6 @@ const char* pdb_get_munged_dial (const SAM_ACCOUNT *sampass) return (NULL); } -uint32 pdb_get_fields_present (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.fields_present); - else - return (-1); -} - uint16 pdb_get_bad_password_count(const SAM_ACCOUNT *sampass) { if (sampass) @@ -1048,16 +1040,6 @@ BOOL pdb_set_plaintext_pw_only (SAM_ACCOUNT *sampass, const char *password, enum return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag); } -BOOL pdb_set_fields_present (SAM_ACCOUNT *sampass, uint32 fields_present, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - sampass->private.fields_present = fields_present; - - return pdb_set_init_flags(sampass, PDB_FIELDS_PRESENT, flag); -} - BOOL pdb_set_bad_password_count(SAM_ACCOUNT *sampass, uint16 bad_password_count, enum pdb_value_state flag) { if (!sampass) diff --git a/source/passdb/pdb_interface.c b/source/passdb/pdb_interface.c index 9bc38fb4449..ea097c10f69 100644 --- a/source/passdb/pdb_interface.c +++ b/source/passdb/pdb_interface.c @@ -119,7 +119,7 @@ static struct pdb_init_function_entry *pdb_find_backend_entry(const char *name) return NULL; } -static NTSTATUS context_setsampwent(struct pdb_context *context, BOOL update) +static NTSTATUS context_setsampwent(struct pdb_context *context, BOOL update, uint16 acb_mask) { NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; @@ -135,7 +135,7 @@ static NTSTATUS context_setsampwent(struct pdb_context *context, BOOL update) return ret; } - while (NT_STATUS_IS_ERR(ret = context->pwent_methods->setsampwent(context->pwent_methods, update))) { + while (NT_STATUS_IS_ERR(ret = context->pwent_methods->setsampwent(context->pwent_methods, update, acb_mask))) { context->pwent_methods = context->pwent_methods->next; if (context->pwent_methods == NULL) return NT_STATUS_UNSUCCESSFUL; @@ -176,7 +176,7 @@ static NTSTATUS context_getsampwent(struct pdb_context *context, SAM_ACCOUNT *us if (context->pwent_methods == NULL) return ret; - context->pwent_methods->setsampwent(context->pwent_methods, False); + context->pwent_methods->setsampwent(context->pwent_methods, False, 0); } user->methods = context->pwent_methods; pdb_force_pw_initialization(user); @@ -857,7 +857,7 @@ static struct pdb_context *pdb_get_static_context(BOOL reload) Backward compatibility functions for the original passdb interface *******************************************************************/ -BOOL pdb_setsampwent(BOOL update) +BOOL pdb_setsampwent(BOOL update, uint16 acb_mask) { struct pdb_context *pdb_context = pdb_get_static_context(False); @@ -865,7 +865,7 @@ BOOL pdb_setsampwent(BOOL update) return False; } - return NT_STATUS_IS_OK(pdb_context->pdb_setsampwent(pdb_context, update)); + return NT_STATUS_IS_OK(pdb_context->pdb_setsampwent(pdb_context, update, acb_mask)); } void pdb_endsampwent(void) @@ -1243,7 +1243,7 @@ static NTSTATUS pdb_default_delete_sam_account (struct pdb_methods *methods, SAM return NT_STATUS_NOT_IMPLEMENTED; } -static NTSTATUS pdb_default_setsampwent(struct pdb_methods *methods, BOOL update) +static NTSTATUS pdb_default_setsampwent(struct pdb_methods *methods, BOOL update, uint16 acb_mask) { return NT_STATUS_NOT_IMPLEMENTED; } diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c index a84b2f35b28..8b7661d9a36 100644 --- a/source/passdb/pdb_ldap.c +++ b/source/passdb/pdb_ldap.c @@ -1,5 +1,5 @@ /* - Unix SMB/CIFS mplementation. + Unix SMB/CIFS implementation. LDAP protocol helper functions for SAMBA Copyright (C) Jean François Micouleau 1998 Copyright (C) Gerald Carter 2001-2003 @@ -476,6 +476,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pstring temp; LOGIN_CACHE *cache_entry = NULL; int pwHistLen; + pstring tmpstring; /* * do a little initialization @@ -635,9 +636,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE), dir_drive)) { - pdb_set_dir_drive( sampass, - talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()), - PDB_DEFAULT ); + pdb_set_dir_drive( sampass, lp_logon_drive(), PDB_DEFAULT ); } else { pdb_set_dir_drive(sampass, dir_drive, PDB_SET); } @@ -649,7 +648,9 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()), PDB_DEFAULT ); } else { - pdb_set_homedir(sampass, homedir, PDB_SET); + pstrcpy( tmpstring, homedir ); + standard_sub_basic( username, tmpstring, sizeof(tmpstring) ); + pdb_set_homedir(sampass, tmpstring, PDB_SET); } if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, @@ -659,7 +660,9 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()), PDB_DEFAULT ); } else { - pdb_set_logon_script(sampass, logon_script, PDB_SET); + pstrcpy( tmpstring, logon_script ); + standard_sub_basic( username, tmpstring, sizeof(tmpstring) ); + pdb_set_logon_script(sampass, tmpstring, PDB_SET); } if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, @@ -669,7 +672,9 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, talloc_sub_basic( sampass->mem_ctx, username, lp_logon_path()), PDB_DEFAULT ); } else { - pdb_set_profile_path(sampass, profile_path, PDB_SET); + pstrcpy( tmpstring, profile_path ); + standard_sub_basic( username, tmpstring, sizeof(tmpstring) ); + pdb_set_profile_path(sampass, tmpstring, PDB_SET); } if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, @@ -782,8 +787,6 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_hours_len(sampass, hours_len, PDB_SET); pdb_set_logon_divs(sampass, logon_divs, PDB_SET); -/* pdb_set_munged_dial(sampass, munged_dial, PDB_SET); */ - if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_BAD_PASSWORD_COUNT), temp)) { /* leave as default */ @@ -1182,33 +1185,48 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, Connect to LDAP server for password enumeration. *********************************************************************/ -static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update) +static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update, uint16 acb_mask) { struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; int rc; - pstring filter; + pstring filter, suffix; char **attr_list; + BOOL machine_mask = False, user_mask = False; pstr_sprintf( filter, "(&%s%s)", lp_ldap_filter(), get_objclass_filter(ldap_state->schema_ver)); all_string_sub(filter, "%u", "*", sizeof(pstring)); + machine_mask = ((acb_mask != 0) && (acb_mask & (ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))); + user_mask = ((acb_mask != 0) && (acb_mask & ACB_NORMAL)); + + if (machine_mask) { + pstrcpy(suffix, lp_ldap_machine_suffix()); + } else if (user_mask) { + pstrcpy(suffix, lp_ldap_user_suffix()); + } else { + pstrcpy(suffix, lp_ldap_suffix()); + } + + DEBUG(10,("ldapsam_setsampwent: LDAP Query for acb_mask 0x%x will use suffix %s\n", + acb_mask, suffix)); + attr_list = get_userattr_list(ldap_state->schema_ver); - rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, - attr_list, &ldap_state->result); + rc = smbldap_search(ldap_state->smbldap_state, suffix, LDAP_SCOPE_SUBTREE, filter, + attr_list, 0, &ldap_state->result); free_attr_list( attr_list ); if (rc != LDAP_SUCCESS) { DEBUG(0, ("ldapsam_setsampwent: LDAP search failed: %s\n", ldap_err2string(rc))); - DEBUG(3, ("ldapsam_setsampwent: Query was: %s, %s\n", lp_ldap_suffix(), filter)); + DEBUG(3, ("ldapsam_setsampwent: Query was: %s, %s\n", suffix, filter)); ldap_msgfree(ldap_state->result); ldap_state->result = NULL; return NT_STATUS_UNSUCCESSFUL; } - DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n", - ldap_count_entries(ldap_state->smbldap_state->ldap_struct, - ldap_state->result))); + DEBUG(2, ("ldapsam_setsampwent: %d entries in the base %s\n", + ldap_count_entries(ldap_state->smbldap_state->ldap_struct, + ldap_state->result), suffix)); ldap_state->entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->result); @@ -1409,62 +1427,7 @@ static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT static BOOL ldapsam_can_pwchange_exop(struct smbldap_state *ldap_state) { - LDAPMessage *msg = NULL; - LDAPMessage *entry = NULL; - char **values = NULL; - char *attrs[] = { "supportedExtension", NULL }; - int rc, num_result, num_values, i; - BOOL result = False; - - rc = smbldap_search(ldap_state, "", LDAP_SCOPE_BASE, "(objectclass=*)", - attrs, 0, &msg); - - if (rc != LDAP_SUCCESS) { - DEBUG(3, ("Could not search rootDSE\n")); - return False; - } - - num_result = ldap_count_entries(ldap_state->ldap_struct, msg); - - if (num_result != 1) { - DEBUG(3, ("Expected one rootDSE, got %d\n", num_result)); - goto done; - } - - entry = ldap_first_entry(ldap_state->ldap_struct, msg); - - if (entry == NULL) { - DEBUG(3, ("Could not retrieve rootDSE\n")); - goto done; - } - - values = ldap_get_values(ldap_state->ldap_struct, entry, - "supportedExtension"); - - if (values == NULL) { - DEBUG(9, ("LDAP Server does not support any extensions\n")); - goto done; - } - - num_values = ldap_count_values(values); - - if (num_values == 0) { - DEBUG(9, ("LDAP Server does not support any extensions\n")); - goto done; - } - - for (i=0; i<num_values; i++) { - if (strcmp(values[i], LDAP_EXOP_MODIFY_PASSWD) == 0) - result = True; - } - - done: - if (values != NULL) - ldap_value_free(values); - if (msg != NULL) - ldap_msgfree(msg); - - return result; + return smbldap_has_extension(ldap_state, LDAP_EXOP_MODIFY_PASSWD); } /******************************************************************** @@ -2267,7 +2230,7 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods, if (!smbldap_get_single_attribute(conn->ldap_struct, entry, "sambaSID", str, sizeof(str)-1)) - goto done; + continue; if (!string_to_sid(&sid, str)) goto done; @@ -2275,7 +2238,7 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods, if (!smbldap_get_single_attribute(conn->ldap_struct, entry, "gidNumber", str, sizeof(str)-1)) - goto done; + continue; gid = strtoul(str, &end, 10); @@ -2291,7 +2254,7 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods, } if (sid_compare(&global_sid_NULL, &(*sids)[0]) == 0) { - DEBUG(3, ("primary group not found\n")); + DEBUG(3, ("primary group of [%s] not found\n", username)); goto done; } diff --git a/source/passdb/pdb_mysql.c b/source/passdb/pdb_mysql.c index 0e6a11d9326..fbe44233245 100644 --- a/source/passdb/pdb_mysql.c +++ b/source/passdb/pdb_mysql.c @@ -120,7 +120,7 @@ static NTSTATUS row_to_sam_account(MYSQL_RES * r, SAM_ACCOUNT * u) return NT_STATUS_OK; } -static NTSTATUS mysqlsam_setsampwent(struct pdb_methods *methods, BOOL update) +static NTSTATUS mysqlsam_setsampwent(struct pdb_methods *methods, BOOL update, uint16 acb_mask) { struct pdb_mysql_data *data = (struct pdb_mysql_data *) methods->private_data; @@ -454,10 +454,9 @@ static NTSTATUS mysqlsam_init(struct pdb_context * pdb_context, struct pdb_metho data->location = smb_xstrdup(location); DEBUG(1, - ("Connecting to database server, host: %s, user: %s, password: %s, database: %s, port: %ld\n", + ("Connecting to database server, host: %s, user: %s, database: %s, port: %ld\n", config_value(data, "mysql host", CONFIG_HOST_DEFAULT), config_value(data, "mysql user", CONFIG_USER_DEFAULT), - config_value(data, "mysql password", CONFIG_PASS_DEFAULT), config_value(data, "mysql database", CONFIG_DB_DEFAULT), xatol(config_value(data, "mysql port", CONFIG_PORT_DEFAULT)))); diff --git a/source/passdb/pdb_pgsql.c b/source/passdb/pdb_pgsql.c index 6578d3d192a..0955ea1881f 100644 --- a/source/passdb/pdb_pgsql.c +++ b/source/passdb/pdb_pgsql.c @@ -118,7 +118,7 @@ static NTSTATUS row_to_sam_account ( PGresult *r, long row, SAM_ACCOUNT *u ) return NT_STATUS_OK ; } -static NTSTATUS pgsqlsam_setsampwent(struct pdb_methods *methods, BOOL update) +static NTSTATUS pgsqlsam_setsampwent(struct pdb_methods *methods, BOOL update, uint16 acb_mask) { struct pdb_pgsql_data *data ; char *query ; diff --git a/source/passdb/pdb_smbpasswd.c b/source/passdb/pdb_smbpasswd.c index d75d0ed5c8c..edb578b1e74 100644 --- a/source/passdb/pdb_smbpasswd.c +++ b/source/passdb/pdb_smbpasswd.c @@ -1226,7 +1226,7 @@ static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state, Functions to be implemented by the new passdb API ****************************************************************/ -static NTSTATUS smbpasswd_setsampwent (struct pdb_methods *my_methods, BOOL update) +static NTSTATUS smbpasswd_setsampwent (struct pdb_methods *my_methods, BOOL update, uint16 acb_mask) { struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data; diff --git a/source/passdb/pdb_sql.c b/source/passdb/pdb_sql.c index 820280bcbf6..ee9ece2baf0 100644 --- a/source/passdb/pdb_sql.c +++ b/source/passdb/pdb_sql.c @@ -141,8 +141,14 @@ static const char * config_value_write(const char *location, const char *name, c swrite = strrchr(v, ':'); /* Default to the same field as read field */ - if (!swrite) + if (!swrite) { + + /* Updating NULL does not make much sense */ + if (!strcmp(v, "NULL")) + return NULL; + return v; + } swrite++; diff --git a/source/passdb/pdb_tdb.c b/source/passdb/pdb_tdb.c index c792d229b9a..755e33940b8 100644 --- a/source/passdb/pdb_tdb.c +++ b/source/passdb/pdb_tdb.c @@ -2,7 +2,7 @@ * Unix SMB/CIFS implementation. * SMB parameters and setup * Copyright (C) Andrew Tridgell 1992-1998 - * Copyright (C) Simo Sorce 2000-2002 + * Copyright (C) Simo Sorce 2000-2003 * Copyright (C) Gerald Carter 2000 * Copyright (C) Jeremy Allison 2001 * Copyright (C) Andrew Bartlett 2002 @@ -42,6 +42,7 @@ static int tdbsam_debug_level = DBGC_ALL; #define PASSDB_FILE_NAME "passdb.tdb" #define USERPREFIX "USER_" #define RIDPREFIX "RID_" +#define PRIVPREFIX "PRIV_" #define tdbsamver_t int32 struct tdbsam_privates { @@ -293,7 +294,7 @@ static int tdbsam_traverse_setpwent(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, Save a list of user keys for iteration. ****************************************************************/ -static NTSTATUS tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update) +static NTSTATUS tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update, uint16 acb_mask) { uint32 flags = update ? (O_RDWR|O_CREAT) : O_RDONLY; @@ -704,6 +705,18 @@ static void free_private_data(void **vp) } + + +/** + * Init tdbsam backend + * + * @param pdb_context initialised passdb context + * @param pdb_method backend methods structure to be filled with function pointers + * @param location the backend tdb file location + * + * @return nt_status code + **/ + static NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) { NTSTATUS nt_status; diff --git a/source/passdb/pdb_xml.c b/source/passdb/pdb_xml.c index 6eb7761a3b4..2a21fc8c9f5 100644 --- a/source/passdb/pdb_xml.c +++ b/source/passdb/pdb_xml.c @@ -307,7 +307,7 @@ static xmlNodePtr parseSambaXMLFile(struct pdb_xml *data) return cur; } -static NTSTATUS xmlsam_setsampwent(struct pdb_methods *methods, BOOL update) +static NTSTATUS xmlsam_setsampwent(struct pdb_methods *methods, BOOL update, uint16 acb_mask) { pdb_xml *data; diff --git a/source/passdb/privileges.c b/source/passdb/privileges.c deleted file mode 100644 index 69fc75a618c..00000000000 --- a/source/passdb/privileges.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * default privileges backend for passdb - * - * Copyright (C) Andrew Tridgell 2003 - * - * 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 (at your option) - * any later version. - * - * This program 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 - * this program; if not, write to the Free Software Foundation, Inc., 675 - * Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "includes.h" - -/* - this is a local implementation of a privileges backend, with - privileges stored in a tdb. Most passdb implementations will - probably use this backend, although some (such as pdb_ldap) will - store the privileges in another manner. - - The basic principle is that the backend should store a list of SIDs - associated with each right, where a right is a string name such as - 'SeTakeOwnershipPrivilege'. The SIDs can be of any type, and do not - need to belong to the local domain. - - The way this is used is that certain places in the code which - require access control will ask the privileges backend 'does this - user have the following privilege'. The 'user' will be a NT_TOKEN, - which is essentially just a list of SIDs. If any of those SIDs are - listed in the list of SIDs for that privilege then the answer will - be 'yes'. That will usually mean that the user gets unconditional - access to that functionality, regradless of any ACLs. In this way - privileges act in a similar fashion to unix setuid bits. -*/ - -/* - The terms 'right' and 'privilege' are used interchangably in this - file. This follows MSDN convention where the LSA calls are calls on - 'rights', which really means privileges. My apologies for the - confusion. -*/ - - -/* 15 seconds seems like an ample time for timeouts on the privileges db */ -#define LOCK_TIMEOUT 15 - - -/* the tdb handle for the privileges database */ -static TDB_CONTEXT *tdb; - - -/* initialise the privilege database */ -BOOL privilege_init(void) -{ - tdb = tdb_open_log(lock_path("privilege.tdb"), 0, TDB_DEFAULT, - O_RDWR|O_CREAT, 0600); - if (!tdb) { - DEBUG(0,("Failed to open privilege database\n")); - return False; - } - - return True; -} - -/* - lock the record for a particular privilege (write lock) -*/ -static NTSTATUS privilege_lock_right(const char *right) -{ - if (tdb_lock_bystring(tdb, right, LOCK_TIMEOUT) != 0) { - return NT_STATUS_INTERNAL_ERROR; - } - return NT_STATUS_OK; -} - -/* - unlock the record for a particular privilege (write lock) -*/ -static void privilege_unlock_right(const char *right) -{ - tdb_unlock_bystring(tdb, right); -} - - -/* - return a list of SIDs that have a particular right -*/ -NTSTATUS privilege_enum_account_with_right(const char *right, - uint32 *count, - DOM_SID **sids) -{ - TDB_DATA data; - char *p; - int i; - - if (!tdb) { - return NT_STATUS_INTERNAL_ERROR; - } - - data = tdb_fetch_bystring(tdb, right); - if (!data.dptr) { - *count = 0; - *sids = NULL; - return NT_STATUS_OK; - } - - /* count them */ - for (i=0, p=data.dptr; p<data.dptr+data.dsize; i++) { - p += strlen(p) + 1; - } - *count = i; - - /* allocate and parse */ - *sids = SMB_MALLOC_ARRAY(DOM_SID, *count); - if (! *sids) { - return NT_STATUS_NO_MEMORY; - } - for (i=0, p=data.dptr; p<data.dptr+data.dsize; i++) { - if (!string_to_sid(&(*sids)[i], p)) { - free(data.dptr); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - p += strlen(p) + 1; - } - - free(data.dptr); - - return NT_STATUS_OK; -} - -/* - set what accounts have a given right - this is an internal interface -*/ -static NTSTATUS privilege_set_accounts_with_right(const char *right, - uint32 count, - DOM_SID *sids) -{ - TDB_DATA data; - char *p; - int i; - - if (!tdb) { - return NT_STATUS_INTERNAL_ERROR; - } - - /* allocate the maximum size that we might use */ - data.dptr = SMB_MALLOC(count * ((MAXSUBAUTHS*11) + 30)); - if (!data.dptr) { - return NT_STATUS_NO_MEMORY; - } - - p = data.dptr; - - for (i=0;i<count;i++) { - sid_to_string(p, &sids[i]); - p += strlen(p) + 1; - } - - data.dsize = PTR_DIFF(p, data.dptr); - - if (tdb_store_bystring(tdb, right, data, TDB_REPLACE) != 0) { - free(data.dptr); - return NT_STATUS_INTERNAL_ERROR; - } - - free(data.dptr); - return NT_STATUS_OK; -} - - -/* - add a SID to the list of SIDs for a right -*/ -NTSTATUS privilege_add_account_right(const char *right, - DOM_SID *sid) -{ - NTSTATUS status; - DOM_SID *current_sids; - uint32 current_count; - int i; - - status = privilege_lock_right(right); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - status = privilege_enum_account_with_right(right, ¤t_count, ¤t_sids); - if (!NT_STATUS_IS_OK(status)) { - privilege_unlock_right(right); - return status; - } - - /* maybe that SID is already listed? this is not an error */ - for (i=0;i<current_count;i++) { - if (sid_equal(¤t_sids[i], sid)) { - privilege_unlock_right(right); - free(current_sids); - return NT_STATUS_OK; - } - } - - /* add it in */ - current_sids = SMB_REALLOC_ARRAY(current_sids, DOM_SID, current_count+1); - if (!current_sids) { - privilege_unlock_right(right); - return NT_STATUS_NO_MEMORY; - } - - sid_copy(¤t_sids[current_count], sid); - current_count++; - - status = privilege_set_accounts_with_right(right, current_count, current_sids); - - free(current_sids); - privilege_unlock_right(right); - - return status; -} - - -/* - remove a SID from the list of SIDs for a right -*/ -NTSTATUS privilege_remove_account_right(const char *right, - DOM_SID *sid) -{ - NTSTATUS status; - DOM_SID *current_sids; - uint32 current_count; - int i; - - status = privilege_lock_right(right); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - status = privilege_enum_account_with_right(right, ¤t_count, ¤t_sids); - if (!NT_STATUS_IS_OK(status)) { - privilege_unlock_right(right); - return status; - } - - for (i=0;i<current_count;i++) { - if (sid_equal(¤t_sids[i], sid)) { - /* found it - so remove it */ - if (current_count-i > 1) { - memmove(¤t_sids[i], ¤t_sids[i+1], - sizeof(current_sids[0]) * ((current_count-i)-1)); - } - current_count--; - status = privilege_set_accounts_with_right(right, - current_count, - current_sids); - free(current_sids); - privilege_unlock_right(right); - return status; - } - } - - /* removing a right that you don't have is not an error */ - - safe_free(current_sids); - privilege_unlock_right(right); - return NT_STATUS_OK; -} - - -/* - an internal function for checking if a SID has a right -*/ -static BOOL privilege_sid_has_right(DOM_SID *sid, const char *right) -{ - NTSTATUS status; - uint32 count; - DOM_SID *sids; - int i; - - status = privilege_enum_account_with_right(right, &count, &sids); - if (!NT_STATUS_IS_OK(status)) { - return False; - } - for (i=0;i<count;i++) { - if (sid_equal(sid, &sids[i])) { - free(sids); - return True; - } - } - - safe_free(sids); - return False; -} - -/* - list the rights for an account. This involves traversing the database -*/ -NTSTATUS privilege_enum_account_rights(DOM_SID *sid, - uint32 *count, - char ***rights) -{ - TDB_DATA key, nextkey; - char *right; - - if (!tdb) { - return NT_STATUS_INTERNAL_ERROR; - } - - *rights = NULL; - *count = 0; - - for (key = tdb_firstkey(tdb); key.dptr; key = nextkey) { - nextkey = tdb_nextkey(tdb, key); - - right = key.dptr; - - if (privilege_sid_has_right(sid, right)) { - (*rights) = SMB_REALLOC_ARRAY(*rights,char *, (*count)+1); - if (! *rights) { - safe_free(nextkey.dptr); - free(key.dptr); - return NT_STATUS_NO_MEMORY; - } - - (*rights)[*count] = SMB_STRDUP(right); - (*count)++; - } - - free(key.dptr); - } - - return NT_STATUS_OK; -} diff --git a/source/passdb/util_sam_sid.c b/source/passdb/util_sam_sid.c index c93c3400bd0..1fddfc79255 100644 --- a/source/passdb/util_sam_sid.c +++ b/source/passdb/util_sam_sid.c @@ -315,28 +315,4 @@ BOOL map_name_to_wellknown_sid(DOM_SID *sid, enum SID_NAME_USE *use, const char return False; } -void add_sid_to_array(const DOM_SID *sid, DOM_SID **sids, int *num) -{ - *sids = SMB_REALLOC_ARRAY(*sids, DOM_SID, (*num)+1); - - if (*sids == NULL) - return; - - sid_copy(&((*sids)[*num]), sid); - *num += 1; - - return; -} - -void add_sid_to_array_unique(const DOM_SID *sid, DOM_SID **sids, int *num_sids) -{ - int i; - - for (i=0; i<(*num_sids); i++) { - if (sid_compare(sid, &(*sids)[i]) == 0) - return; - } - - add_sid_to_array(sid, sids, num_sids); -} |