syncing up with HEAD. Seems to be a lot of differences creeping in
authorGerald Carter <jerry@samba.org>
Tue, 1 Oct 2002 18:26:00 +0000 (18:26 +0000)
committerGerald Carter <jerry@samba.org>
Tue, 1 Oct 2002 18:26:00 +0000 (18:26 +0000)
(i ignored the new SAMBA stuff, but the rest of this looks like it should
have been merged already).

19 files changed:
source/Doxyfile
source/Makefile.in
source/client/client.c
source/include/ads.h
source/lib/charcnv.c
source/lib/util_seaccess.c
source/lib/util_sid.c
source/lib/util_str.c
source/libads/ads_status.c
source/libads/ads_struct.c
source/libads/ads_utils.c
source/libads/disp_sec.c
source/libads/krb5_setpw.c
source/libads/ldap.c
source/libads/sasl.c
source/nsswitch/winbindd_ads.c
source/rpc_server/srv_samr_nt.c
source/rpc_server/srv_spoolss_nt.c
source/utils/net_rpc_samsync.c

index fe71065c24cbf146b7d6741713c6bb9dc75f076c..bbdc5da7e7a542c2b4d5f8aacedfc923618f0f36 100644 (file)
@@ -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
index bd09ee55c885e25c38ec3434922db18ab053a574..32c2e3f70f3b80751fcb610b6909269f0d06fbc8 100644 (file)
@@ -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
 
index eb6b57276089a6407f374bc08b734d15b908c6ba..f25ed1623b0d96c865620a5ffecf90b9f2f86856 100644 (file)
@@ -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"));
index 0181ae535e02e4560f2c3a0a2083655a71b7211d..88a90229b1c8700cd15ae62653db82b10bac5b5d 100644 (file)
@@ -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
index cd8aa4fe55f75f823c6b1b2107e69156f95bc466..d0cef52c9230b00e2cd5f052e361176db0e03673 100644 (file)
@@ -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);  
 }
 
 /****************************************************************************
index b137023e55cfa5b83ae581d8b61109e12df1dd3b..456d7ba9e295e45f1ef8c8e37d28060ba44eada4 100644 (file)
@@ -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)
 {
index e9635fc7f84b20dfb5af4a2563e34701cf912312..1439471f64bdf308eff3034015adeabeb4c6f2a9 100644 (file)
@@ -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);
index 1b38db2c9465d8fca543884c07943065bbfa9e61..75338de4d3f409dd7f81c420fb14f7ff3f6ee4b5 100644 (file)
@@ -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;
index d85f9c9b58a557e58eaa2281a0b54b0b93da8cde..80fdb99eac0567f068c205723788020c3446b868 100644 (file)
@@ -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;
 }
index b68c822ce3519513e8160b42e0f8918201a4396d..3cdd015bf46909c02a9a5efc0e26fc497c21ff3d 100644 (file)
@@ -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);
index fc8a27002114901182a0d3910c05cb9ec09b0c70..626c1779266c9a2f31b35bae8ddcf6a70f7ebd46 100644 (file)
@@ -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;
+}
index a930fd6fe09b0530f66b6dae81bf7385bbb8a2e6..a7b0bf6f07ca35c37323e447460763c98f257331 100644 (file)
@@ -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
 
index a49b6cbe3b0ee8a01ed6ec30286544d0e175921c..8079c0953fc65391ce936228bb6e715d23b21dd8 100644 (file)
@@ -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
index 7a0afb1a8167d29d6920b6f70f60495facdfd76f..2133bf0719d291661475c2e7f1fdd1a7e62a1f3e 100644 (file)
@@ -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);
 
index f7dd01084a2f9c1fc70ec685522200ac39dd97dd..aa7d99a5f7c9579dd2647405da5c9f3f2197681c 100644 (file)
@@ -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 
index 4f91ed0f20c31c325b6e1a4a1672c10c22436d24..228c4a2a0880c8777ec8fca7308c1e3683cc31f5 100644 (file)
 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));
index c5a2c54511546f501e1e63206ae01b0cca1abc1c..020a3c6aafd7f7fa32777787301076d68a2a9f8d 100644 (file)
@@ -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) {
index e60a1d20638aa510551194876351fa133cacc81f..f942a685a1e56cf118522059571310bb4db40cdc 100644 (file)
@@ -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();
index 202d5b5c88e604ebb6f2df8057a5a0196d658cf7..c040b3cca2fff0787946bd6b51d0b7e4d82d54e2 100644 (file)
@@ -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);