summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2002-10-01 18:26:00 +0000
committerGerald Carter <jerry@samba.org>2002-10-01 18:26:00 +0000
commitf2d1f19a66ebaf9b88d23c0faa2412536cc74cda (patch)
tree781120ed548c3f38de9d40795a426de525e7865b /source3
parent2fb5c7c580a3fff3c7d477b65a1c4852af86433b (diff)
downloadsamba-f2d1f19a66ebaf9b88d23c0faa2412536cc74cda.tar.gz
samba-f2d1f19a66ebaf9b88d23c0faa2412536cc74cda.tar.bz2
samba-f2d1f19a66ebaf9b88d23c0faa2412536cc74cda.zip
syncing up with HEAD. Seems to be a lot of differences creeping in
(i ignored the new SAMBA stuff, but the rest of this looks like it should have been merged already). (This used to be commit 3de09e5cf1f667e410ee8b9516a956860ce7290f)
Diffstat (limited to 'source3')
-rw-r--r--source3/Doxyfile8
-rw-r--r--source3/Makefile.in3
-rw-r--r--source3/client/client.c21
-rw-r--r--source3/include/ads.h7
-rw-r--r--source3/lib/charcnv.c4
-rw-r--r--source3/lib/util_seaccess.c2
-rw-r--r--source3/lib/util_sid.c31
-rw-r--r--source3/lib/util_str.c4
-rw-r--r--source3/libads/ads_status.c6
-rw-r--r--source3/libads/ads_struct.c1
-rw-r--r--source3/libads/ads_utils.c20
-rw-r--r--source3/libads/disp_sec.c3
-rw-r--r--source3/libads/krb5_setpw.c31
-rw-r--r--source3/libads/ldap.c202
-rw-r--r--source3/libads/sasl.c4
-rw-r--r--source3/nsswitch/winbindd_ads.c197
-rw-r--r--source3/rpc_server/srv_samr_nt.c4
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c10
-rw-r--r--source3/utils/net_rpc_samsync.c44
19 files changed, 291 insertions, 311 deletions
diff --git a/source3/Doxyfile b/source3/Doxyfile
index fe71065c24..bbdc5da7e7 100644
--- a/source3/Doxyfile
+++ b/source3/Doxyfile
@@ -124,7 +124,7 @@ MAN_LINKS = NO
#---------------------------------------------------------------------------
GENERATE_XML = NO
#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
+# configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = NO
MACRO_EXPANSION = NO
@@ -136,14 +136,14 @@ PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
-# Configuration::addtions related to external references
+# configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
+# configuration options related to the dot tool
#---------------------------------------------------------------------------
HAVE_DOT = YES
CLASS_GRAPH = YES
@@ -159,7 +159,7 @@ MAX_DOT_GRAPH_HEIGHT = 1024
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
-# Configuration::addtions related to the search engine
+# configuration::additions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO
CGI_NAME = search.cgi
diff --git a/source3/Makefile.in b/source3/Makefile.in
index bd09ee55c8..32c2e3f70f 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -154,7 +154,8 @@ PARAM_OBJ = param/loadparm.o param/params.o dynconfig.o
LIBADS_OBJ = libads/ldap.o libads/ldap_printer.o libads/sasl.o \
libads/krb5_setpw.o libads/kerberos.o libads/ldap_user.o \
libads/ads_struct.o libads/ads_status.o \
- libads/disp_sec.o libads/ads_utils.o
+ libads/disp_sec.o libads/ads_utils.o libads/ldap_utils.o \
+ libads/ads_ldap.o
LIBADS_SERVER_OBJ = libads/util.o libads/kerberos_verify.o
diff --git a/source3/client/client.c b/source3/client/client.c
index eb6b572760..f25ed1623b 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -2436,9 +2436,24 @@ static struct cli_state *do_connect(const char *server, const char *share)
if (!cli_send_tconX(c, sharename, "?????",
password, strlen(password)+1)) {
- d_printf("tree connect failed: %s\n", cli_errstr(c));
- cli_shutdown(c);
- return NULL;
+ pstring full_share;
+
+ /*
+ * Some servers require \\server\share for the share
+ * while others are happy with share as we gave above
+ * Lets see if we give it the long form if it works
+ */
+ pstrcpy(full_share, "\\\\");
+ pstrcat(full_share, server);
+ pstrcat(full_share, "\\");
+ pstrcat(full_share, sharename);
+ if (!cli_send_tconX(c, full_share, "?????", password,
+ strlen(password) + 1)) {
+
+ d_printf("tree connect failed: %s\n", cli_errstr(c));
+ cli_shutdown(c);
+ return NULL;
+ }
}
DEBUG(4,(" tconx ok\n"));
diff --git a/source3/include/ads.h b/source3/include/ads.h
index 0181ae535e..88a90229b1 100644
--- a/source3/include/ads.h
+++ b/source3/include/ads.h
@@ -15,6 +15,7 @@ typedef struct {
char *realm;
char *workgroup;
char *ldap_server;
+ char *ldap_uri;
int foreign; /* set to 1 if connecting to a foreign realm */
} server;
@@ -255,5 +256,7 @@ typedef void **ADS_MODLIST;
/* ads auth control flags */
-#define ADS_AUTH_DISABLE_KERBEROS 1
-#define ADS_AUTH_NO_BIND 2
+#define ADS_AUTH_DISABLE_KERBEROS 0x01
+#define ADS_AUTH_NO_BIND 0x02
+#define ADS_AUTH_ANON_BIND 0x04
+#define ADS_AUTH_SIMPLE_BIND 0x08
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c
index cd8aa4fe55..d0cef52c92 100644
--- a/source3/lib/charcnv.c
+++ b/source3/lib/charcnv.c
@@ -522,12 +522,12 @@ int push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
*
* @retval The number of bytes occupied by the string in the destination
**/
-int push_utf8_allocate(void **dest, const char *src)
+int push_utf8_allocate(char **dest, const char *src)
{
int src_len = strlen(src)+1;
*dest = NULL;
- return convert_string_allocate(CH_UNIX, CH_UTF8, src, src_len, dest);
+ return convert_string_allocate(CH_UNIX, CH_UTF8, src, src_len, (void **)dest);
}
/****************************************************************************
diff --git a/source3/lib/util_seaccess.c b/source3/lib/util_seaccess.c
index b137023e55..456d7ba9e2 100644
--- a/source3/lib/util_seaccess.c
+++ b/source3/lib/util_seaccess.c
@@ -226,7 +226,7 @@ void se_map_standard(uint32 *access_mask, struct standard_mapping *mapping)
"Access-Checking" document in MSDN.
*****************************************************************************/
-BOOL se_access_check(SEC_DESC *sd, const NT_USER_TOKEN *token,
+BOOL se_access_check(const SEC_DESC *sd, const NT_USER_TOKEN *token,
uint32 acc_desired, uint32 *acc_granted,
NTSTATUS *status)
{
diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c
index e9635fc7f8..1439471f64 100644
--- a/source3/lib/util_sid.c
+++ b/source3/lib/util_sid.c
@@ -34,6 +34,7 @@ DOM_SID global_sid_World_Domain; /* Everyone domain */
DOM_SID global_sid_World; /* Everyone */
DOM_SID global_sid_Creator_Owner_Domain; /* Creator Owner domain */
DOM_SID global_sid_NT_Authority; /* NT Authority */
+DOM_SID global_sid_System; /* System */
DOM_SID global_sid_NULL; /* NULL sid */
DOM_SID global_sid_Authenticated_Users; /* All authenticated rids */
DOM_SID global_sid_Network; /* Network rids */
@@ -58,6 +59,12 @@ NT_USER_TOKEN anonymous_token = {
anon_sid_array
};
+static DOM_SID system_sid_array[4];
+NT_USER_TOKEN system_token = {
+ 1,
+ system_sid_array
+};
+
/****************************************************************************
Lookup string names for SID types.
****************************************************************************/
@@ -101,6 +108,10 @@ const char *sid_type_lookup(uint32 sid_type)
void generate_wellknown_sids(void)
{
+ static BOOL initialised = False;
+ if (initialised)
+ return;
+
string_to_sid(&global_sid_Builtin, "S-1-5-32");
string_to_sid(&global_sid_Builtin_Administrators, "S-1-5-32-544");
string_to_sid(&global_sid_Builtin_Users, "S-1-5-32-545");
@@ -111,6 +122,7 @@ void generate_wellknown_sids(void)
string_to_sid(&global_sid_Creator_Owner, "S-1-3-0");
string_to_sid(&global_sid_Creator_Group, "S-1-3-1");
string_to_sid(&global_sid_NT_Authority, "S-1-5");
+ string_to_sid(&global_sid_System, "S-1-5-18");
string_to_sid(&global_sid_NULL, "S-1-0-0");
string_to_sid(&global_sid_Authenticated_Users, "S-1-5-11");
string_to_sid(&global_sid_Network, "S-1-5-2");
@@ -120,6 +132,17 @@ void generate_wellknown_sids(void)
sid_copy( &anonymous_token.user_sids[0], &global_sid_World);
sid_copy( &anonymous_token.user_sids[1], &global_sid_Network);
sid_copy( &anonymous_token.user_sids[2], &global_sid_Anonymous);
+
+ /* Create the system token. */
+ sid_copy( &system_token.user_sids[0], &global_sid_System);
+
+ initialised = True;
+}
+
+NT_USER_TOKEN *get_system_token(void)
+{
+ generate_wellknown_sids(); /* The token is initialised here */
+ return &system_token;
}
/**************************************************************************
@@ -347,7 +370,7 @@ void sid_copy(DOM_SID *dst, const DOM_SID *src)
/*****************************************************************
Write a sid out into on-the-wire format.
*****************************************************************/
-BOOL sid_linearize(char *outbuf, size_t len, DOM_SID *sid)
+BOOL sid_linearize(char *outbuf, size_t len, const DOM_SID *sid)
{
size_t i;
@@ -366,7 +389,7 @@ BOOL sid_linearize(char *outbuf, size_t len, DOM_SID *sid)
/*****************************************************************
parse a on-the-wire SID to a DOM_SID
*****************************************************************/
-BOOL sid_parse(char *inbuf, size_t len, DOM_SID *sid)
+BOOL sid_parse(const char *inbuf, size_t len, DOM_SID *sid)
{
int i;
if (len < 8) return False;
@@ -482,7 +505,7 @@ BOOL sid_check_is_in_builtin(const DOM_SID *sid)
Calculates size of a sid.
*****************************************************************/
-size_t sid_size(DOM_SID *sid)
+size_t sid_size(const DOM_SID *sid)
{
if (sid == NULL)
return 0;
@@ -518,7 +541,7 @@ BOOL non_mappable_sid(DOM_SID *sid)
return the binary string representation of a DOM_SID
caller must free
*/
-char *sid_binstring(DOM_SID *sid)
+char *sid_binstring(const DOM_SID *sid)
{
char *buf, *s;
int len = sid_size(sid);
diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c
index 1b38db2c94..75338de4d3 100644
--- a/source3/lib/util_str.c
+++ b/source3/lib/util_str.c
@@ -468,7 +468,7 @@ char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, si
for(i = 0; i < len; i++) {
int val = (src[i] & 0xff);
- if(isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
+ if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
dest[i] = src[i];
else
dest[i] = '_';
@@ -501,7 +501,7 @@ char *StrnCpy(char *dest,const char *src,size_t n)
like strncpy but copies up to the character marker. always null terminates.
returns a pointer to the character marker in the source string (src).
****************************************************************************/
-char *strncpyn(char *dest, const char *src,size_t n, char c)
+char *strncpyn(char *dest, const char *src, size_t n, char c)
{
char *p;
size_t str_len;
diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c
index d85f9c9b58..80fdb99eac 100644
--- a/source3/libads/ads_status.c
+++ b/source3/libads/ads_status.c
@@ -72,6 +72,12 @@ NTSTATUS ads_ntstatus(ADS_STATUS status)
if (status.error_type == ADS_ERROR_NT){
return status.err.nt_status;
}
+#ifdef HAVE_LDAP
+ if ((status.error_type == ADS_ERROR_LDAP)
+ && (status.err.rc == LDAP_NO_MEMORY)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+#endif
if (ADS_ERR_OK(status)) return NT_STATUS_OK;
return NT_STATUS_UNSUCCESSFUL;
}
diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c
index b68c822ce3..3cdd015bf4 100644
--- a/source3/libads/ads_struct.c
+++ b/source3/libads/ads_struct.c
@@ -122,6 +122,7 @@ void ads_destroy(ADS_STRUCT **ads)
SAFE_FREE((*ads)->server.realm);
SAFE_FREE((*ads)->server.workgroup);
SAFE_FREE((*ads)->server.ldap_server);
+ SAFE_FREE((*ads)->server.ldap_uri);
SAFE_FREE((*ads)->auth.realm);
SAFE_FREE((*ads)->auth.password);
diff --git a/source3/libads/ads_utils.c b/source3/libads/ads_utils.c
index fc8a270021..626c177926 100644
--- a/source3/libads/ads_utils.c
+++ b/source3/libads/ads_utils.c
@@ -3,7 +3,8 @@
ads (active directory) utility library
Copyright (C) Stefan (metze) Metzmacher 2002
-
+ Copyright (C) Andrew Tridgell 2001
+
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
@@ -21,9 +22,6 @@
#include "includes.h"
-#ifdef HAVE_ADS
-
-
/*
translated the ACB_CTRL Flags to UserFlags (userAccountControl)
*/
@@ -168,4 +166,16 @@ uint32 ads_gtype2atype(uint32 gtype)
return atype;
}
-#endif
+/* turn a sAMAccountType into a SID_NAME_USE */
+enum SID_NAME_USE ads_atype_map(uint32 atype)
+{
+ switch (atype & 0xF0000000) {
+ case ATYPE_GLOBAL_GROUP:
+ return SID_NAME_DOM_GRP;
+ case ATYPE_ACCOUNT:
+ return SID_NAME_USER;
+ default:
+ DEBUG(1,("hmm, need to map account type 0x%x\n", atype));
+ }
+ return SID_NAME_UNKNOWN;
+}
diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c
index a930fd6fe0..a7b0bf6f07 100644
--- a/source3/libads/disp_sec.c
+++ b/source3/libads/disp_sec.c
@@ -20,8 +20,6 @@
#include "includes.h"
-#ifdef HAVE_ADS
-
static struct perm_mask_str {
uint32 mask;
char *str;
@@ -158,5 +156,4 @@ void ads_disp_sd(SEC_DESC *sd)
printf("-------------- End Of Security Descriptor\n");
}
-#endif
diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c
index a49b6cbe3b..8079c0953f 100644
--- a/source3/libads/krb5_setpw.c
+++ b/source3/libads/krb5_setpw.c
@@ -471,4 +471,35 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server,
}
+/**
+ * Set the machine account password
+ * @param ads connection to ads server
+ * @param hostname machine whose password is being set
+ * @param password new password
+ * @return status of password change
+ **/
+ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads,
+ const char *hostname,
+ const char *password)
+{
+ ADS_STATUS status;
+ char *host = strdup(hostname);
+ char *principal;
+
+ strlower(host);
+
+ /*
+ we need to use the '$' form of the name here, as otherwise the
+ server might end up setting the password for a user instead
+ */
+ asprintf(&principal, "%s$@%s", host, ads->auth.realm);
+
+ status = krb5_set_password(ads->auth.kdc_server, principal, password, ads->auth.time_offset);
+
+ free(host);
+ free(principal);
+
+ return status;
+}
+
#endif
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index 7a0afb1a81..2133bf0719 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -22,7 +22,7 @@
#include "includes.h"
-#ifdef HAVE_ADS
+#ifdef HAVE_LDAP
/**
* @file ldap.c
@@ -67,6 +67,29 @@ static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port)
return True;
}
+/*
+ try a connection to a given ldap server, based on URL, returning True if successful
+ */
+static BOOL ads_try_connect_uri(ADS_STRUCT *ads)
+{
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
+ DEBUG(5,("ads_try_connect: trying ldap server at URI '%s'\n",
+ ads->server.ldap_uri));
+
+
+ if (ldap_initialize((LDAP**)&(ads->ld), ads->server.ldap_uri) == LDAP_SUCCESS) {
+ return True;
+ }
+ DEBUG(0, ("ldap_initialize: %s\n", strerror(errno)));
+
+#else
+
+ DEBUG(1, ("no URL support in LDAP libs!\n"));
+#endif
+
+ return False;
+}
+
/* used by the IP comparison function */
struct ldap_ip {
struct in_addr ip;
@@ -210,6 +233,13 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
ads->last_attempt = time(NULL);
ads->ld = NULL;
+ /* try with a URL based server */
+
+ if (ads->server.ldap_uri &&
+ ads_try_connect_uri(ads)) {
+ goto got_connection;
+ }
+
/* try with a user specified server */
if (ads->server.ldap_server &&
ads_try_connect(ads, ads->server.ldap_server, LDAP_PORT)) {
@@ -278,6 +308,14 @@ got_connection:
return ADS_SUCCESS;
}
+ if (ads->auth.flags & ADS_AUTH_ANON_BIND) {
+ return ADS_ERROR(ldap_simple_bind_s( ads->ld, NULL, NULL));
+ }
+
+ if (ads->auth.flags & ADS_AUTH_SIMPLE_BIND) {
+ return ADS_ERROR(ldap_simple_bind_s( ads->ld, ads->auth.user_name, ads->auth.password));
+ }
+
return ads_sasl_bind(ads);
}
@@ -741,7 +779,11 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host)
/* the easiest way to find a machine account anywhere in the tree
is to look for hostname$ */
- asprintf(&exp, "(samAccountName=%s$)", host);
+ if (asprintf(&exp, "(samAccountName=%s$)", host) == -1) {
+ DEBUG(1, ("asprintf failed!\n"));
+ return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+
status = ads_search(ads, res, exp, attrs);
free(exp);
return status;
@@ -898,13 +940,15 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods)
controls[0] = &PermitModify;
controls[1] = NULL;
- push_utf8_allocate((void **) &utf8_dn, mod_dn);
+ if (push_utf8_allocate(&utf8_dn, mod_dn) == -1) {
+ return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
/* find the end of the list, marked by NULL or -1 */
for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++);
/* make sure the end of the list is NULL */
mods[i] = NULL;
- ret = ldap_modify_ext_s(ads->ld, utf8_dn ? utf8_dn : mod_dn,
+ ret = ldap_modify_ext_s(ads->ld, utf8_dn,
(LDAPMod **) mods, controls, NULL);
SAFE_FREE(utf8_dn);
return ADS_ERROR(ret);
@@ -922,7 +966,10 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods)
int ret, i;
char *utf8_dn = NULL;
- push_utf8_allocate((void **) &utf8_dn, new_dn);
+ if (push_utf8_allocate(&utf8_dn, new_dn) == -1) {
+ DEBUG(1, ("ads_gen_add: push_utf8_allocate failed!"));
+ return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
/* find the end of the list, marked by NULL or -1 */
for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++);
@@ -944,7 +991,11 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn)
{
int ret;
char *utf8_dn = NULL;
- push_utf8_allocate((void **) &utf8_dn, del_dn);
+ if (push_utf8_allocate(&utf8_dn, del_dn) == -1) {
+ DEBUG(1, ("ads_del_dn: push_utf8_allocate failed!"));
+ return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+
ret = ldap_delete(ads->ld, utf8_dn ? utf8_dn : del_dn);
return ADS_ERROR(ret);
}
@@ -991,6 +1042,10 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname,
if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm)))
goto done;
ou_str = ads_ou_string(org_unit);
+ if (!ou_str) {
+ DEBUG(1, ("ads_ou_string returned NULL (malloc failure?)\n"));
+ goto done;
+ }
new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", hostname, ou_str,
ads->config.bind_path);
free(ou_str);
@@ -1320,9 +1375,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn)
const char *attrs[] = {"ntSecurityDescriptor", "objectSid", 0};
char *exp = 0;
size_t sd_size = 0;
- struct berval **bvals = 0;
struct berval bval = {0, NULL};
- prs_struct ps;
prs_struct ps_wire;
LDAPMessage *res = 0;
@@ -1339,37 +1392,39 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn)
ret = ADS_ERROR(LDAP_SUCCESS);
- asprintf(&exp, "(samAccountName=%s$)", hostname);
+ if (asprintf(&exp, "(samAccountName=%s$)", hostname) == -1) {
+ DEBUG(1, ("ads_set_machine_sd: asprintf failed!\n"));
+ return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+
ret = ads_search(ads, (void *) &res, exp, attrs);
if (!ADS_ERR_OK(ret)) return ret;
msg = ads_first_entry(ads, res);
- bvals = ldap_get_values_len(ads->ld, msg, attrs[0]);
ads_pull_sid(ads, msg, attrs[1], &sid);
- ads_msgfree(ads, res);
-#if 0
- file_save("/tmp/sec_desc.old", bvals[0]->bv_val, bvals[0]->bv_len);
-#endif
- if (!(ctx = talloc_init_named("sec_io_desc")))
- return ADS_ERROR(LDAP_NO_MEMORY);
-
- prs_init(&ps, bvals[0]->bv_len, ctx, UNMARSHALL);
- prs_append_data(&ps, bvals[0]->bv_val, bvals[0]->bv_len);
- ps.data_offset = 0;
- ldap_value_free_len(bvals);
+ if (!(ctx = talloc_init_named("sec_io_desc"))) {
+ ret = ADS_ERROR(LDAP_NO_MEMORY);
+ goto ads_set_sd_error;
+ }
- if (!sec_io_desc("sd", &psd, &ps, 1))
+ if (!ads_pull_sd(ads, ctx, msg, attrs[0], &psd)) {
+ ret = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
goto ads_set_sd_error;
+ }
status = sec_desc_add_sid(ctx, &psd, &sid, SEC_RIGHTS_FULL_CTRL, &sd_size);
- if (!NT_STATUS_IS_OK(status))
+ if (!NT_STATUS_IS_OK(status)) {
+ ret = ADS_ERROR_NT(status);
goto ads_set_sd_error;
+ }
prs_init(&ps_wire, sd_size, ctx, MARSHALL);
- if (!sec_io_desc("sd_wire", &psd, &ps_wire, 1))
+ if (!sec_io_desc("sd_wire", &psd, &ps_wire, 1)) {
+ ret = ADS_ERROR(LDAP_NO_MEMORY);
goto ads_set_sd_error;
+ }
#if 0
file_save("/tmp/sec_desc.new", ps_wire.data_p, sd_size);
@@ -1381,47 +1436,11 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn)
ads_mod_ber(ctx, &mods, attrs[0], &bval);
ret = ads_gen_mod(ads, dn, mods);
- prs_mem_free(&ps);
- prs_mem_free(&ps_wire);
- talloc_destroy(ctx);
- return ret;
-
ads_set_sd_error:
- prs_mem_free(&ps);
+ ads_msgfree(ads, res);
prs_mem_free(&ps_wire);
talloc_destroy(ctx);
- return ADS_ERROR(LDAP_NO_MEMORY);
-}
-
-/**
- * Set the machine account password
- * @param ads connection to ads server
- * @param hostname machine whose password is being set
- * @param password new password
- * @return status of password change
- **/
-ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads,
- const char *hostname,
- const char *password)
-{
- ADS_STATUS status;
- char *host = strdup(hostname);
- char *principal;
-
- strlower(host);
-
- /*
- we need to use the '$' form of the name here, as otherwise the
- server might end up setting the password for a user instead
- */
- asprintf(&principal, "%s$@%s", host, ads->auth.realm);
-
- status = krb5_set_password(ads->auth.kdc_server, principal, password, ads->auth.time_offset);
-
- free(host);
- free(principal);
-
- return status;
+ return ret;
}
/**
@@ -1596,6 +1615,60 @@ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
return count;
}
+/**
+ * pull a SEC_DESC from a ADS result
+ * @param ads connection to ads server
+ * @param mem_ctx TALLOC_CTX for allocating sid array
+ * @param msg Results of search
+ * @param field Attribute to retrieve
+ * @param sd Pointer to *SEC_DESC to store result (talloc()ed)
+ * @return boolean inidicating success
+*/
+BOOL ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
+ void *msg, const char *field, SEC_DESC **sd)
+{
+ struct berval **values;
+ prs_struct ps;
+ BOOL ret = False;
+
+ values = ldap_get_values_len(ads->ld, msg, field);
+
+ if (!values) return False;
+
+ if (values[0]) {
+ prs_init(&ps, values[0]->bv_len, mem_ctx, UNMARSHALL);
+ prs_append_data(&ps, values[0]->bv_val, values[0]->bv_len);
+ ps.data_offset = 0;
+
+ ret = sec_io_desc("sd", sd, &ps, 1);
+ }
+
+ ldap_value_free_len(values);
+ return ret;
+}
+
+/*
+ * in order to support usernames longer than 21 characters we need to
+ * use both the sAMAccountName and the userPrincipalName attributes
+ * It seems that not all users have the userPrincipalName attribute set
+ *
+ * @param ads connection to ads server
+ * @param mem_ctx TALLOC_CTX for allocating sid array
+ * @param msg Results of search
+ * @return the username
+ */
+char *ads_pull_username(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg)
+{
+ char *ret, *p;
+
+ ret = ads_pull_string(ads, mem_ctx, msg, "userPrincipalName");
+ if (ret && (p = strchr(ret, '@'))) {
+ *p = 0;
+ return ret;
+ }
+ return ads_pull_string(ads, mem_ctx, msg, "sAMAccountName");
+}
+
/**
* find the update serial number - this is the core of the ldap cache
@@ -1705,8 +1778,9 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads)
ads->config.realm = strdup(p+2);
ads->config.bind_path = ads_build_dn(ads->config.realm);
- DEBUG(3,("got ldap server name %s@%s\n",
- ads->config.ldap_server_name, ads->config.realm));
+ DEBUG(3,("got ldap server name %s@%s, using bind path: %s\n",
+ ads->config.ldap_server_name, ads->config.realm,
+ ads->config.bind_path));
ads->config.current_time = ads_parse_time(timestr);
diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c
index f7dd01084a..aa7d99a5f7 100644
--- a/source3/libads/sasl.c
+++ b/source3/libads/sasl.c
@@ -20,7 +20,7 @@
#include "includes.h"
-#ifdef HAVE_ADS
+#ifdef HAVE_LDAP
/*
perform a LDAP/SASL/SPNEGO/NTLMSSP bind (just how many layers can
@@ -190,10 +190,12 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
}
DEBUG(3,("got principal=%s\n", principal));
+#ifdef HAVE_KRB5
if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) &&
got_kerberos_mechanism && ads_kinit_password(ads) == 0) {
return ads_sasl_spnego_krb5_bind(ads, principal);
}
+#endif
/* lets do NTLMSSP ... this has the big advantage that we don't need
to sync clocks, and we don't rely on special versions of the krb5
diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c
index 4f91ed0f20..228c4a2a08 100644
--- a/source3/nsswitch/winbindd_ads.c
+++ b/source3/nsswitch/winbindd_ads.c
@@ -32,74 +32,6 @@ static char *primary_realm;
/*
- a wrapper around ldap_search_s that retries depending on the error code
- this is supposed to catch dropped connections and auto-reconnect
-*/
-ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope,
- const char *exp,
- const char **attrs, void **res)
-{
- ADS_STATUS status;
- int count = 3;
- char *bp;
-
- if (!ads->ld &&
- time(NULL) - ads->last_attempt < ADS_RECONNECT_TIME) {
- return ADS_ERROR(LDAP_SERVER_DOWN);
- }
-
- bp = strdup(bind_path);
-
- while (count--) {
- status = ads_do_search_all(ads, bp, scope, exp, attrs, res);
- if (ADS_ERR_OK(status)) {
- DEBUG(5,("Search for %s gave %d replies\n",
- exp, ads_count_replies(ads, *res)));
- free(bp);
- return status;
- }
-
- if (*res) ads_msgfree(ads, *res);
- *res = NULL;
- DEBUG(3,("Reopening ads connection to realm '%s' after error %s\n",
- ads->config.realm, ads_errstr(status)));
- if (ads->ld) {
- ldap_unbind(ads->ld);
- }
- ads->ld = NULL;
- status = ads_connect(ads);
- if (!ADS_ERR_OK(status)) {
- DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n",
- ads_errstr(status)));
- ads_destroy(&ads);
- free(bp);
- return status;
- }
- }
- free(bp);
-
- DEBUG(1,("ads reopen failed after error %s\n", ads_errstr(status)));
- return status;
-}
-
-
-ADS_STATUS ads_search_retry(ADS_STRUCT *ads, void **res,
- const char *exp,
- const char **attrs)
-{
- return ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE,
- exp, attrs, res);
-}
-
-ADS_STATUS ads_search_retry_dn(ADS_STRUCT *ads, void **res,
- const char *dn,
- const char **attrs)
-{
- return ads_do_search_retry(ads, dn, LDAP_SCOPE_BASE,
- "(objectclass=*)", attrs, res);
-}
-
-/*
return our ads connections structure for a domain. We keep the connection
open to make things faster
*/
@@ -166,37 +98,6 @@ static void sid_from_rid(struct winbindd_domain *domain, uint32 rid, DOM_SID *si
sid_append_rid(sid, rid);
}
-/* turn a sAMAccountType into a SID_NAME_USE */
-static enum SID_NAME_USE ads_atype_map(uint32 atype)
-{
- switch (atype & 0xF0000000) {
- case ATYPE_GLOBAL_GROUP:
- return SID_NAME_DOM_GRP;
- case ATYPE_ACCOUNT:
- return SID_NAME_USER;
- default:
- DEBUG(1,("hmm, need to map account type 0x%x\n", atype));
- }
- return SID_NAME_UNKNOWN;
-}
-
-/*
- in order to support usernames longer than 21 characters we need to
- use both the sAMAccountName and the userPrincipalName attributes
- It seems that not all users have the userPrincipalName attribute set
-*/
-static char *pull_username(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg)
-{
- char *ret, *p;
-
- ret = ads_pull_string(ads, mem_ctx, msg, "userPrincipalName");
- if (ret && (p = strchr(ret, '@'))) {
- *p = 0;
- return ret;
- }
- return ads_pull_string(ads, mem_ctx, msg, "sAMAccountName");
-}
-
/* Query display info for a realm. This is the basic user list fn */
static NTSTATUS query_user_list(struct winbindd_domain *domain,
@@ -254,7 +155,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
continue;
}
- name = pull_username(ads, mem_ctx, msg);
+ name = ads_pull_username(ads, mem_ctx, msg);
gecos = ads_pull_string(ads, mem_ctx, msg, "name");
if (!ads_pull_sid(ads, msg, "objectSid", &sid)) {
DEBUG(1,("No sid for %s !?\n", name));
@@ -341,7 +242,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
&account_type) ||
!(account_type & ATYPE_GLOBAL_GROUP)) continue;
- name = pull_username(ads, mem_ctx, msg);
+ name = ads_pull_username(ads, mem_ctx, msg);
gecos = ads_pull_string(ads, mem_ctx, msg, "name");
if (!ads_pull_sid(ads, msg, "objectSid", &sid)) {
DEBUG(1,("No sid for %s !?\n", name));
@@ -371,63 +272,21 @@ done:
return status;
}
-
/* convert a single name to a sid in a domain */
static NTSTATUS name_to_sid(struct winbindd_domain *domain,
const char *name,
DOM_SID *sid,
enum SID_NAME_USE *type)
{
- ADS_STRUCT *ads = NULL;
- const char *attrs[] = {"objectSid", "sAMAccountType", NULL};
- int count;
- ADS_STATUS rc;
- void *res = NULL;
- char *exp;
- uint32 t;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+ ADS_STRUCT *ads;
DEBUG(3,("ads: name_to_sid\n"));
ads = ads_cached_connection(domain);
- if (!ads) goto done;
-
- /* accept either the win2000 or the pre-win2000 username */
- asprintf(&exp, "(|(sAMAccountName=%s)(userPrincipalName=%s@%s))",
- name, name, ads->config.realm);
- rc = ads_search_retry(ads, &res, exp, attrs);
- free(exp);
- if (!ADS_ERR_OK(rc)) {
- DEBUG(1,("name_to_sid ads_search: %s\n", ads_errstr(rc)));
- goto done;
- }
+ if (!ads)
+ return NT_STATUS_UNSUCCESSFUL;
- count = ads_count_replies(ads, res);
- if (count != 1) {
- DEBUG(1,("name_to_sid: %s not found\n", name));
- goto done;
- }
-
- if (!ads_pull_sid(ads, res, "objectSid", sid)) {
- DEBUG(1,("No sid for %s !?\n", name));
- goto done;
- }
-
- if (!ads_pull_uint32(ads, res, "sAMAccountType", &t)) {
- DEBUG(1,("No sAMAccountType for %s !?\n", name));
- goto done;
- }
-
- *type = ads_atype_map(t);
-
- status = NT_STATUS_OK;
-
- DEBUG(3,("ads name_to_sid mapped %s\n", name));
-
-done:
- if (res) ads_msgfree(ads, res);
-
- return status;
+ return ads_name_to_sid(ads, name, sid, type);
}
/* convert a sid to a user or group name */
@@ -438,46 +297,12 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
enum SID_NAME_USE *type)
{
ADS_STRUCT *ads = NULL;
- const char *attrs[] = {"userPrincipalName",
- "sAMAccountName",
- "sAMAccountType", NULL};
- ADS_STATUS rc;
- void *msg = NULL;
- char *exp;
- char *sidstr;
- uint32 atype;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
-
DEBUG(3,("ads: sid_to_name\n"));
-
ads = ads_cached_connection(domain);
- if (!ads) goto done;
-
- sidstr = sid_binstring(sid);
- asprintf(&exp, "(objectSid=%s)", sidstr);
- rc = ads_search_retry(ads, &msg, exp, attrs);
- free(exp);
- free(sidstr);
- if (!ADS_ERR_OK(rc)) {
- DEBUG(1,("sid_to_name ads_search: %s\n", ads_errstr(rc)));
- goto done;
- }
-
- if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype)) {
- goto done;
- }
-
- *name = pull_username(ads, mem_ctx, msg);
- *type = ads_atype_map(atype);
-
- status = NT_STATUS_OK;
-
- DEBUG(3,("ads sid_to_name mapped %s\n", *name));
-
-done:
- if (msg) ads_msgfree(ads, msg);
+ if (!ads)
+ return NT_STATUS_UNSUCCESSFUL;
- return status;
+ return ads_sid_to_name(ads, mem_ctx, sid, name, type);
}
@@ -504,7 +329,7 @@ static BOOL dn_lookup(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
goto failed;
}
- (*name) = pull_username(ads, mem_ctx, res);
+ (*name) = ads_pull_username(ads, mem_ctx, res);
if (!ads_pull_uint32(ads, res, "sAMAccountType", &atype)) {
goto failed;
@@ -566,7 +391,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
goto done;
}
- info->acct_name = pull_username(ads, mem_ctx, msg);
+ info->acct_name = ads_pull_username(ads, mem_ctx, msg);
info->full_name = ads_pull_string(ads, mem_ctx, msg, "name");
if (!ads_pull_sid(ads, msg, "objectSid", &sid)) {
DEBUG(1,("No sid for %d !?\n", user_rid));
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index c5a2c54511..020a3c6aaf 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -894,7 +894,7 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM
/* well-known aliases */
if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
- enum_group_mapping(SID_NAME_ALIAS, &map, (int *)&num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
+ enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
if (num_entries != 0) {
*d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
@@ -1328,7 +1328,7 @@ NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAM
!sid_check_is_in_builtin(&sid))
return NT_STATUS_OBJECT_TYPE_MISMATCH;
- if (!get_local_group_from_sid(sid, &map, MAPPING_WITHOUT_PRIV))
+ if (!get_group_map_from_sid(sid, &map, MAPPING_WITHOUT_PRIV))
return NT_STATUS_NO_SUCH_ALIAS;
switch (q_u->switch_level) {
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index e60a1d2063..f942a685a1 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -313,11 +313,6 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
return WERR_BADFID;
}
- if (del_a_printer(Printer->dev.handlename) != 0) {
- DEBUG(3,("Error deleting printer %s\n", Printer->dev.handlename));
- return WERR_BADFID;
- }
-
/*
* It turns out that Windows allows delete printer on a handle
* opened by an admin user, then used on a pipe handle created
@@ -342,6 +337,11 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
}
#endif
+ if (del_a_printer(Printer->dev.handlename) != 0) {
+ DEBUG(3,("Error deleting printer %s\n", Printer->dev.handlename));
+ return WERR_BADFID;
+ }
+
if (*lp_deleteprinter_cmd()) {
char *cmd = lp_deleteprinter_cmd();
diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c
index 202d5b5c88..c040b3cca2 100644
--- a/source3/utils/net_rpc_samsync.c
+++ b/source3/utils/net_rpc_samsync.c
@@ -4,6 +4,7 @@
Copyright (C) Andrew Tridgell 2002
Copyright (C) Tim Potter 2001,2002
+ Modified by Volker Lendecke 2002
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
@@ -191,7 +192,6 @@ fail:
static NTSTATUS
sam_account_from_delta(SAM_ACCOUNT *account, SAM_ACCOUNT_INFO *delta)
{
- DOM_SID sid;
fstring s;
uchar lm_passwd[16], nt_passwd[16];
@@ -227,13 +227,8 @@ sam_account_from_delta(SAM_ACCOUNT *account, SAM_ACCOUNT_INFO *delta)
/* User and group sid */
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, delta->user_rid);
- pdb_set_user_sid(account, &sid);
-
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, delta->group_rid);
- pdb_set_group_sid(account, &sid);
+ pdb_set_user_sid_from_rid(account, delta->user_rid);
+ pdb_set_group_sid_from_rid(account, delta->group_rid);
/* Logon and password information */
@@ -359,17 +354,10 @@ fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta)
fstring sid_string;
GROUP_MAP map;
int flag = TDB_INSERT;
- gid_t gid;
unistr2_to_ascii(name, &delta->uni_grp_name, sizeof(name)-1);
unistr2_to_ascii(comment, &delta->uni_grp_desc, sizeof(comment)-1);
- if ((grp = getgrnam(name)) == NULL)
- smb_create_group(name, &gid);
-
- if ((grp = getgrgid(gid)) == NULL)
- return NT_STATUS_ACCESS_DENIED;
-
/* add the group to the mapping table */
sid_copy(&group_sid, get_global_sam_sid());
sid_append_rid(&group_sid, rid);
@@ -382,17 +370,17 @@ fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta)
if (grp == NULL)
{
- gid_t new_gid;
+ gid_t gid;
+
/* No group found from mapping, find it from its name. */
if ((grp = getgrnam(name)) == NULL) {
/* No appropriate group found, create one */
d_printf("Creating unix group: '%s'\n", name);
- if (smb_create_group(name, &new_gid) != 0)
+ if (smb_create_group(name, &gid) != 0)
+ return NT_STATUS_ACCESS_DENIED;
+ if ((grp = getgrgid(gid)) == NULL)
return NT_STATUS_ACCESS_DENIED;
}
-
- if ((grp = getgrgid(new_gid)) == NULL)
- return NT_STATUS_ACCESS_DENIED;
}
map.gid = grp->gr_gid;
@@ -558,22 +546,26 @@ static NTSTATUS fetch_alias_info(uint32 rid, SAM_ALIAS_INFO *delta,
}
if (grp == NULL) {
- gid_t new_gid;
+ gid_t gid;
+
/* No group found from mapping, find it from its name. */
if ((grp = getgrnam(name)) == NULL) {
/* No appropriate group found, create one */
d_printf("Creating unix group: '%s'\n", name);
- if (smb_create_group(name, &new_gid) != 0)
+ if (smb_create_group(name, &gid) != 0)
+ return NT_STATUS_ACCESS_DENIED;
+ if ((grp = getgrgid(gid)) == NULL)
return NT_STATUS_ACCESS_DENIED;
}
-
- if ((grp = getgrgid(new_gid)) == NULL)
- return NT_STATUS_ACCESS_DENIED;
}
map.gid = grp->gr_gid;
map.sid = alias_sid;
- map.sid_name_use = SID_NAME_ALIAS;
+
+ if (sid_equal(&dom_sid, &global_sid_Builtin))
+ map.sid_name_use = SID_NAME_WKN_GRP;
+ else
+ map.sid_name_use = SID_NAME_ALIAS;
fstrcpy(map.nt_name, name);
fstrcpy(map.comment, comment);