r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text
[vlendec/samba-autobuild/.git] / source3 / libads / ads_struct.c
index a7c8d1a6813ef068bba861d87514834660d26d99..b01e0879ef9cab970a7537b33064abd87656ccb7 100644 (file)
@@ -1,13 +1,12 @@
 /* 
-   Unix SMB/Netbios implementation.
-   Version 3.0
+   Unix SMB/CIFS implementation.
    ads (active directory) utility library
    Copyright (C) Andrew Tridgell 2001
    Copyright (C) Andrew Bartlett 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
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    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.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 
-char *ads_build_dn(const char *realm)
+/* return a ldap dn path from a string, given separators and field name
+   caller must free
+*/
+char *ads_build_path(const char *realm, const char *sep, const char *field, int reverse)
 {
        char *p, *r;
-       int numdots = 0;
+       int numbits = 0;
        char *ret;
        int len;
        
-       r = strdup(realm);
+       r = SMB_STRDUP(realm);
 
-       if (!r || !*r) return r;
+       if (!r || !*r)
+               return r;
 
-       for (p=r; *p; p++) {
-               if (*p == '.') numdots++;
-       }
+       for (p=r; *p; p++)
+               if (strchr(sep, *p))
+                       numbits++;
 
-       len = (numdots+1)*4 + strlen(r) + 1;
+       len = (numbits+1)*(strlen(field)+1) + strlen(r) + 1;
 
-       ret = malloc(len);
-       strlcpy(ret,"dc=", len);
-       p=strtok(r,"."); 
-       strlcat(ret, p, len);
+       ret = (char *)SMB_MALLOC(len);
+       if (!ret)
+               return NULL;
 
-       while ((p=strtok(NULL,"."))) {
-               strlcat(ret,",dc=", len);
+       strlcpy(ret,field, len);
+       p=strtok(r,sep); 
+       if (p) {
                strlcat(ret, p, len);
+       
+               while ((p=strtok(NULL,sep))) {
+                       char *s;
+                       if (reverse)
+                               asprintf(&s, "%s%s,%s", field, p, ret);
+                       else
+                               asprintf(&s, "%s,%s%s", ret, field, p);
+                       free(ret);
+                       ret = s;
+               }
        }
 
        free(r);
-
        return ret;
 }
 
-
-#ifdef HAVE_LDAP
-/*
-  find the ldap server from DNS
+/* return a dn of the form "dc=AA,dc=BB,dc=CC" from a 
+   realm of the form AA.BB.CC 
+   caller must free
 */
-static char *find_ldap_server(ADS_STRUCT *ads)
+char *ads_build_dn(const char *realm)
 {
-       char *list = NULL;
-       struct in_addr ip;
-
-       if (ads->realm && 
-           ldap_domain2hostlist(ads->realm, &list) == LDAP_SUCCESS) {
-               char *p;
-               p = strchr(list, ':');
-               if (p) *p = 0;
-               return list;
-       }
+       return ads_build_path(realm, ".", "dc=", 0);
+}
 
-       /* get desperate, find the domain controller IP */
-       if (resolve_name(lp_workgroup(), &ip, 0x1B)) {
-               return strdup(inet_ntoa(ip));
-       }
+/* return a DNS name in the for aa.bb.cc from the DN  
+   "dc=AA,dc=BB,dc=CC".  caller must free
+*/
+char *ads_build_domain(const char *dn)
+{
+       char *dnsdomain = NULL;
+       
+       /* result should always be shorter than the DN */
 
-       return NULL;
-}
+       if ( (dnsdomain = SMB_STRDUP( dn )) == NULL ) {
+               DEBUG(0,("ads_build_domain: malloc() failed!\n"));              
+               return NULL;            
+       }       
 
-#else 
+       strlower_m( dnsdomain );        
+       all_string_sub( dnsdomain, "dc=", "", 0);
+       all_string_sub( dnsdomain, ",", ".", 0 );
 
-static char *find_ldap_server(ADS_STRUCT *ads)
-{
-       /* Without LDAP this doesn't make much sense */
-       return NULL;
+       return dnsdomain;       
 }
 
-#endif 
+
 
 #ifndef LDAP_PORT
 #define LDAP_PORT 389
@@ -98,41 +105,29 @@ static char *find_ldap_server(ADS_STRUCT *ads)
   initialise a ADS_STRUCT, ready for some ads_ ops
 */
 ADS_STRUCT *ads_init(const char *realm, 
-                    const char *ldap_server,
-                    const char *bind_path,
-                    const char *password)
+                    const char *workgroup,
+                    const char *ldap_server)
 {
        ADS_STRUCT *ads;
        
-       ads = (ADS_STRUCT *)smb_xmalloc(sizeof(*ads));
+       ads = SMB_XMALLOC_P(ADS_STRUCT);
        ZERO_STRUCTP(ads);
        
-       ads->realm = realm? strdup(realm) : NULL;
-       ads->ldap_server = ldap_server? strdup(ldap_server) : NULL;
-       ads->bind_path = bind_path? strdup(bind_path) : NULL;
-       ads->ldap_port = LDAP_PORT;
-       if (password) ads->password = strdup(password);
-
-       if (!ads->realm) {
-               ads->realm = strdup(lp_realm());
-               if (!ads->realm[0]) {
-                       SAFE_FREE(ads->realm);
-               }
-       }
-       if (!ads->bind_path && ads->realm) {
-               ads->bind_path = ads_build_dn(ads->realm);
-       }
-       if (!ads->ldap_server) {
-               ads->ldap_server = strdup(lp_ads_server());
-               if (!ads->ldap_server[0]) {
-                       ads->ldap_server = find_ldap_server(ads);
-               }
+       ads->server.realm = realm? SMB_STRDUP(realm) : NULL;
+       ads->server.workgroup = workgroup ? SMB_STRDUP(workgroup) : NULL;
+       ads->server.ldap_server = ldap_server? SMB_STRDUP(ldap_server) : NULL;
+
+       /* we need to know if this is a foreign realm */
+       if (realm && *realm && !strequal(lp_realm(), realm)) {
+               ads->server.foreign = 1;
        }
-       if (!ads->kdc_server) {
-               /* assume its the same as LDAP */
-               ads->kdc_server = ads->ldap_server? strdup(ads->ldap_server) : NULL;
+       if (workgroup && *workgroup && !strequal(lp_workgroup(), workgroup)) {
+               ads->server.foreign = 1;
        }
 
+       /* the caller will own the memory by default */
+       ads->is_mine = 1;
+
        return ads;
 }
 
@@ -142,44 +137,32 @@ ADS_STRUCT *ads_init(const char *realm,
 void ads_destroy(ADS_STRUCT **ads)
 {
        if (ads && *ads) {
+               BOOL is_mine;
+
+               is_mine = (*ads)->is_mine;
 #if HAVE_LDAP
-               if ((*ads)->ld) ldap_unbind((*ads)->ld);
+               if ((*ads)->ld) {
+                       ldap_unbind((*ads)->ld);
+               }
 #endif
-               SAFE_FREE((*ads)->realm);
-               SAFE_FREE((*ads)->ldap_server);
-               SAFE_FREE((*ads)->ldap_server_name);
-               SAFE_FREE((*ads)->kdc_server);
-               SAFE_FREE((*ads)->bind_path);
-               SAFE_FREE((*ads)->password);
-               SAFE_FREE((*ads)->user_name);
+               SAFE_FREE((*ads)->server.realm);
+               SAFE_FREE((*ads)->server.workgroup);
+               SAFE_FREE((*ads)->server.ldap_server);
+
+               SAFE_FREE((*ads)->auth.realm);
+               SAFE_FREE((*ads)->auth.password);
+               SAFE_FREE((*ads)->auth.user_name);
+               SAFE_FREE((*ads)->auth.kdc_server);
+
+               SAFE_FREE((*ads)->config.realm);
+               SAFE_FREE((*ads)->config.bind_path);
+               SAFE_FREE((*ads)->config.ldap_server_name);
+               SAFE_FREE((*ads)->config.server_site_name);
+               SAFE_FREE((*ads)->config.client_site_name);
+               
                ZERO_STRUCTP(*ads);
-               SAFE_FREE(*ads);
-       }
-}
-
-
-static void ads_display_status_helper(char *m, OM_uint32 code, int type)
-{
-     int maj_stat, min_stat;
-     gss_buffer_desc msg;
-     int msg_ctx;
-     
-     msg_ctx = 0;
-     while (1) {
-         maj_stat = gss_display_status(&min_stat, code,
-                                      type, GSS_C_NULL_OID,
-                                      &msg_ctx, &msg);
-         DEBUG(1, ("GSS-API error %s: %s\n", m,
-                     (char *)msg.value)); 
-         (void) gss_release_buffer(&min_stat, &msg);
-         
-         if (!msg_ctx)
-              break;
-     }
-}
 
-void ads_display_status(char * msg, int maj_stat,int min_stat)
-{
-     ads_display_status_helper(msg, maj_stat, GSS_C_GSS_CODE);
-     ads_display_status_helper(msg, min_stat, GSS_C_MECH_CODE);
+               if ( is_mine )
+                       SAFE_FREE(*ads);
+       }
 }