libads/ldap.c

basic ldap client-side routines for ads server communications [詳細]

ソースコードを見る。

関数

static void gotalarm_sig (void)
LDAP * ldap_open_with_timeout (const char *server, int port, unsigned int to)
static int ldap_search_with_timeout (LDAP *ld, LDAP_CONST char *base, int scope, LDAP_CONST char *filter, char **attrs, int attrsonly, LDAPControl **sctrls, LDAPControl **cctrls, int sizelimit, LDAPMessage **res)
BOOL ads_sitename_match (ADS_STRUCT *ads)
BOOL ads_closest_dc (ADS_STRUCT *ads)
BOOL ads_try_connect (ADS_STRUCT *ads, const char *server)
static NTSTATUS ads_find_dc (ADS_STRUCT *ads)
ADS_STATUS ads_connect (ADS_STRUCT *ads)
 Connect to the LDAP server
static struct berval * dup_berval (TALLOC_CTX *ctx, const struct berval *in_val)
static struct berval ** ads_dup_values (TALLOC_CTX *ctx, const struct berval **in_vals)
static char ** ads_push_strvals (TALLOC_CTX *ctx, const char **in_vals)
static char ** ads_pull_strvals (TALLOC_CTX *ctx, const char **in_vals)
static ADS_STATUS ads_do_paged_search_args (ADS_STRUCT *ads, const char *bind_path, int scope, const char *expr, const char **attrs, void *args, LDAPMessage **res, int *count, struct berval **cookie)
 Do a search with paged results.
static ADS_STATUS ads_do_paged_search (ADS_STRUCT *ads, const char *bind_path, int scope, const char *expr, const char **attrs, LDAPMessage **res, int *count, struct berval **cookie)
ADS_STATUS ads_do_search_all_args (ADS_STRUCT *ads, const char *bind_path, int scope, const char *expr, const char **attrs, void *args, LDAPMessage **res)
 Get all results for a search.
ADS_STATUS ads_do_search_all (ADS_STRUCT *ads, const char *bind_path, int scope, const char *expr, const char **attrs, LDAPMessage **res)
ADS_STATUS ads_do_search_all_fn (ADS_STRUCT *ads, const char *bind_path, int scope, const char *expr, const char **attrs, BOOL(*fn)(char *, void **, void *), void *data_area)
 Run a function on all results for a search.
ADS_STATUS ads_do_search (ADS_STRUCT *ads, const char *bind_path, int scope, const char *expr, const char **attrs, LDAPMessage **res)
 Do a search with a timeout.
ADS_STATUS ads_search (ADS_STRUCT *ads, LDAPMessage **res, const char *expr, const char **attrs)
 Do a general ADS search
ADS_STATUS ads_search_dn (ADS_STRUCT *ads, LDAPMessage **res, const char *dn, const char **attrs)
 Do a search on a specific DistinguishedName
void ads_msgfree (ADS_STRUCT *ads, LDAPMessage *msg)
 Free up memory from a ads_search
void ads_memfree (ADS_STRUCT *ads, void *mem)
 Free up memory from various ads requests
char * ads_get_dn (ADS_STRUCT *ads, LDAPMessage *msg)
 Get a dn from search results
char * ads_parent_dn (const char *dn)
 Get the parent from a dn
ADS_STATUS ads_find_machine_acct (ADS_STRUCT *ads, LDAPMessage **res, const char *machine)
 Find a machine account given a hostname
ADS_MODLIST ads_init_mods (TALLOC_CTX *ctx)
 Initialize a list of mods to be used in a modify request
static ADS_STATUS ads_modlist_add (TALLOC_CTX *ctx, ADS_MODLIST *mods, int mod_op, const char *name, const void *_invals)
ADS_STATUS ads_mod_str (TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const char *val)
 Add a single string value to a mod list
ADS_STATUS ads_mod_strlist (TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const char **vals)
 Add an array of string values to a mod list
static ADS_STATUS ads_mod_ber (TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const struct berval *val)
 Add a single ber-encoded value to a mod list
ADS_STATUS ads_gen_mod (ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods)
 Perform an ldap modify
ADS_STATUS ads_gen_add (ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods)
 Perform an ldap add
ADS_STATUS ads_del_dn (ADS_STRUCT *ads, char *del_dn)
 Delete a DistinguishedName
char * ads_ou_string (ADS_STRUCT *ads, const char *org_unit)
 Build an org unit string if org unit is Computers or blank then assume a container, otherwise assume a / separated list of organisational units.
char * ads_default_ou_string (ADS_STRUCT *ads, const char *wknguid)
 Get a org unit string for a well-known GUID
ADS_STATUS ads_add_strlist (TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const char **vals)
 Adds (appends) an item to an attribute array, rather then replacing the whole list
uint32 ads_get_kvno (ADS_STRUCT *ads, const char *machine_name)
 Determines the computer account's current KVNO via an LDAP lookup
ADS_STATUS ads_clear_service_principal_names (ADS_STRUCT *ads, const char *machine_name)
 This clears out all registered spn's for a given hostname
ADS_STATUS ads_add_service_principal_name (ADS_STRUCT *ads, const char *machine_name, const char *my_fqdn, const char *spn)
 This adds a service principal name to an existing computer account (found by hostname) in AD.
ADS_STATUS ads_create_machine_acct (ADS_STRUCT *ads, const char *machine_name, const char *org_unit)
 adds a machine account to the ADS server
static void dump_binary (const char *field, struct berval **values)
static void dump_guid (const char *field, struct berval **values)
static void dump_sid (const char *field, struct berval **values)
static void dump_sd (const char *filed, struct berval **values)
static void dump_string (const char *field, char **values)
static BOOL ads_dump_field (char *field, void **values, void *data_area)
void ads_dump (ADS_STRUCT *ads, LDAPMessage *res)
 Dump a result from LDAP on stdout used for debugging
void ads_process_results (ADS_STRUCT *ads, LDAPMessage *res, BOOL(*fn)(char *, void **, void *), void *data_area)
 Walk through results, calling a function for each entry found.
int ads_count_replies (ADS_STRUCT *ads, void *res)
 count how many replies are in a LDAPMessage
LDAPMessage * ads_first_entry (ADS_STRUCT *ads, LDAPMessage *res)
 pull the first entry from a ADS result
LDAPMessage * ads_next_entry (ADS_STRUCT *ads, LDAPMessage *res)
 pull the next entry from a ADS result
LDAPMessage * ads_first_message (ADS_STRUCT *ads, LDAPMessage *res)
 pull the first message from a ADS result
LDAPMessage * ads_next_message (ADS_STRUCT *ads, LDAPMessage *res)
 pull the next message from a ADS result
char * ads_pull_string (ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, LDAPMessage *msg, const char *field)
 pull a single string from a ADS result
char ** ads_pull_strings (ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, LDAPMessage *msg, const char *field, size_t *num_values)
 pull an array of strings from a ADS result
char ** ads_pull_strings_range (ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, LDAPMessage *msg, const char *field, char **current_strings, const char **next_attribute, size_t *num_strings, BOOL *more_strings)
 pull an array of strings from a ADS result (handle large multivalue attributes with range retrieval)
BOOL ads_pull_uint32 (ADS_STRUCT *ads, LDAPMessage *msg, const char *field, uint32 *v)
 pull a single uint32 from a ADS result
BOOL ads_pull_guid (ADS_STRUCT *ads, LDAPMessage *msg, struct GUID *guid)
 pull a single objectGUID from an ADS result
BOOL ads_pull_sid (ADS_STRUCT *ads, LDAPMessage *msg, const char *field, DOM_SID *sid)
 pull a single DOM_SID from a ADS result
int ads_pull_sids (ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, LDAPMessage *msg, const char *field, DOM_SID **sids)
 pull an array of DOM_SIDs from a ADS result
BOOL ads_pull_sd (ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, LDAPMessage *msg, const char *field, SEC_DESC **sd)
 pull a SEC_DESC from a ADS result
char * ads_pull_username (ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, LDAPMessage *msg)
ADS_STATUS ads_USN (ADS_STRUCT *ads, uint32 *usn)
 find the update serial number - this is the core of the ldap cache
static time_t ads_parse_time (const char *str)
ADS_STATUS ads_current_time (ADS_STRUCT *ads)
ADS_STATUS ads_domain_func_level (ADS_STRUCT *ads, uint32 *val)
ADS_STATUS ads_domain_sid (ADS_STRUCT *ads, DOM_SID *sid)
 find the domain sid for our domain
ADS_STATUS ads_site_dn (ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char **site_name)
 find our site name
ADS_STATUS ads_site_dn_for_machine (ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char *computer_name, const char **site_dn)
 find the site dn where a machine resides
ADS_STATUS ads_upn_suffixes (ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char ***suffixes, size_t *num_suffixes)
 get the upn suffixes for a domain
BOOL ads_get_sid_from_extended_dn (TALLOC_CTX *mem_ctx, const char *dn, enum ads_extended_dn_flags flags, DOM_SID *sid)
 pull a DOM_SID from an extended dn string
int ads_pull_sids_from_extendeddn (ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, LDAPMessage *msg, const char *field, enum ads_extended_dn_flags flags, DOM_SID **sids)
 pull an array of DOM_SIDs from a ADS result
char * ads_get_dnshostname (ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name)
char * ads_get_upn (ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name)
char * ads_get_samaccountname (ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name)
SAVED CODE we used to join
via ldap remember how we did
this JRA ADS_STATUS 
ads_join_realm (ADS_STRUCT *ads, const char *machine_name, uint32 account_type, const char *org_unit)
 Join a machine to a realm Creates the machine account and sets the machine password
ADS_STATUS ads_leave_realm (ADS_STRUCT *ads, const char *hostname)
 Delete a machine from the realm

変数

static SIG_ATOMIC_T gotalarm


説明

basic ldap client-side routines for ads server communications

The routines contained here should do the necessary ldap calls for ads setups.

Important note: attribute names passed into ads_ routines must already be in UTF-8 format. We do not convert them because in almost all cases, they are just ascii (which is represented with the same codepoints in UTF-8). This may have to change at some point

ldap.c で定義されています。


関数

static void gotalarm_sig ( void   )  [static]

ldap.c51 行で定義されています。

参照先 gotalarm.

00052 {
00053         gotalarm = 1;
00054 }

LDAP* ldap_open_with_timeout ( const char *  server,
int  port,
unsigned int  to 
)

ldap.c56 行で定義されています。

参照先 CatchSignal()errnogotalarmgotalarm_sig()strerror().

参照元 ads_connect()get_ldap_seq().

00057 {
00058         LDAP *ldp = NULL;
00059 
00060         /* Setup timeout */
00061         gotalarm = 0;
00062         CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
00063         alarm(to);
00064         /* End setup timeout. */
00065 
00066         ldp = ldap_open(server, port);
00067 
00068         if (ldp == NULL) {
00069                 DEBUG(2,("Could not open LDAP connection to %s:%d: %s\n",
00070                          server, port, strerror(errno)));
00071         }
00072 
00073         /* Teardown timeout. */
00074         CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
00075         alarm(0);
00076 
00077         return ldp;
00078 }

static int ldap_search_with_timeout ( LDAP *  ld,
LDAP_CONST char *  base,
int  scope,
LDAP_CONST char *  filter,
char **  attrs,
int  attrsonly,
LDAPControl **  sctrls,
LDAPControl **  cctrls,
int  sizelimit,
LDAPMessage **  res 
) [static]

ldap.c80 行で定義されています。

参照先 CatchSignal()gotalarmgotalarm_sig()result.

参照元 ads_do_paged_search_args()ads_do_search().

00090 {
00091         struct timeval timeout;
00092         int result;
00093 
00094         /* Setup timeout for the ldap_search_ext_s call - local and remote. */
00095         timeout.tv_sec = lp_ldap_timeout();
00096         timeout.tv_usec = 0;
00097 
00098         /* Setup alarm timeout.... Do we need both of these ? JRA. */
00099         gotalarm = 0;
00100         CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
00101         alarm(lp_ldap_timeout());
00102         /* End setup timeout. */
00103 
00104         result = ldap_search_ext_s(ld, base, scope, filter, attrs,
00105                                    attrsonly, sctrls, cctrls, &timeout,
00106                                    sizelimit, res);
00107 
00108         /* Teardown timeout. */
00109         CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
00110         alarm(0);
00111 
00112         if (gotalarm != 0)
00113                 return LDAP_TIMELIMIT_EXCEEDED;
00114 
00115         return result;
00116 }

BOOL ads_sitename_match ( ADS_STRUCT ads  ) 

ldap.c122 行で定義されています。

参照先 ADS_STRUCT::client_site_nameADS_STRUCT::configADS_STRUCT::server_site_namestrequal().

参照元 ads_closest_dc().

00123 {
00124         if (ads->config.server_site_name == NULL &&
00125             ads->config.client_site_name == NULL ) {
00126                 DEBUG(10,("ads_sitename_match: both null\n"));
00127                 return True;
00128         }
00129         if (ads->config.server_site_name &&
00130             ads->config.client_site_name &&
00131             strequal(ads->config.server_site_name,
00132                      ads->config.client_site_name)) {
00133                 DEBUG(10,("ads_sitename_match: name %s match\n", ads->config.server_site_name));
00134                 return True;
00135         }
00136         DEBUG(10,("ads_sitename_match: no match between server: %s and client: %s\n",
00137                 ads->config.server_site_name ? ads->config.server_site_name : "NULL",
00138                 ads->config.client_site_name ? ads->config.client_site_name : "NULL"));
00139         return False;
00140 }

BOOL ads_closest_dc ( ADS_STRUCT ads  ) 

ldap.c146 行で定義されています。

参照先 ads_sitename_match()ADS_STRUCT::configADS_STRUCT::flagsADS_STRUCT::ldap_server_name.

参照元 ads_connect()ads_dc_name()dcip_to_name().

00147 {
00148         if (ads->config.flags & ADS_CLOSEST) {
00149                 DEBUG(10,("ads_closest_dc: ADS_CLOSEST flag set\n"));
00150                 return True;
00151         }
00152 
00153         /* not sure if this can ever happen */
00154         if (ads_sitename_match(ads)) {
00155                 DEBUG(10,("ads_closest_dc: ADS_CLOSEST flag not set but sites match\n"));
00156                 return True;
00157         }
00158 
00159         DEBUG(10,("ads_closest_dc: %s is not the closest DC\n", 
00160                 ads->config.ldap_server_name));
00161 
00162         return False;
00163 }

BOOL ads_try_connect ( ADS_STRUCT ads,
const char *  server 
)

ldap.c170 行で定義されています。

参照先 ads_build_dn()ads_cldap_netlogon()ADS_STRUCT::bind_pathcldap_netlogon_reply::client_site_nameADS_STRUCT::client_site_nameADS_STRUCT::configcldap_netlogon_reply::domainADS_STRUCT::flagscldap_netlogon_reply::flagscldap_netlogon_reply::hostnameinterpret_addr2()ADS_STRUCT::ldap_ipADS_STRUCT::ldap_portADS_STRUCT::ldap_server_namecldap_netlogon_reply::netbios_domainADS_STRUCT::realmADS_STRUCT::servercldap_netlogon_reply::server_site_nameADS_STRUCT::server_site_namesitename_store()strupper_m()ADS_STRUCT::workgroup.

参照元 ads_connect()ads_find_dc()dcip_to_name().

00171 {
00172         char *srv;
00173         struct cldap_netlogon_reply cldap_reply;
00174 
00175         if (!server || !*server) {
00176                 return False;
00177         }
00178         
00179         DEBUG(5,("ads_try_connect: sending CLDAP request to %s (realm: %s)\n", 
00180                 server, ads->server.realm));
00181 
00182         /* this copes with inet_ntoa brokenness */
00183         
00184         srv = SMB_STRDUP(server);
00185 
00186         ZERO_STRUCT( cldap_reply );
00187 
00188         if ( !ads_cldap_netlogon( srv, ads->server.realm, &cldap_reply ) ) {
00189                 DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", srv));
00190                 SAFE_FREE( srv );
00191                 return False;
00192         }
00193 
00194         /* Check the CLDAP reply flags */
00195 
00196         if ( !(cldap_reply.flags & ADS_LDAP) ) {
00197                 DEBUG(1,("ads_try_connect: %s's CLDAP reply says it is not an LDAP server!\n",
00198                         srv));
00199                 SAFE_FREE( srv );
00200                 return False;
00201         }
00202 
00203         /* Fill in the ads->config values */
00204 
00205         SAFE_FREE(ads->config.realm);
00206         SAFE_FREE(ads->config.bind_path);
00207         SAFE_FREE(ads->config.ldap_server_name);
00208         SAFE_FREE(ads->config.server_site_name);
00209         SAFE_FREE(ads->config.client_site_name);
00210         SAFE_FREE(ads->server.workgroup);
00211 
00212         ads->config.flags              = cldap_reply.flags;
00213         ads->config.ldap_server_name   = SMB_STRDUP(cldap_reply.hostname);
00214         strupper_m(cldap_reply.domain);
00215         ads->config.realm              = SMB_STRDUP(cldap_reply.domain);
00216         ads->config.bind_path          = ads_build_dn(ads->config.realm);
00217         if (*cldap_reply.server_site_name) {
00218                 ads->config.server_site_name =
00219                         SMB_STRDUP(cldap_reply.server_site_name);
00220         }
00221         if (*cldap_reply.client_site_name) {
00222                 ads->config.client_site_name =
00223                         SMB_STRDUP(cldap_reply.client_site_name);
00224         }
00225                 
00226         ads->server.workgroup          = SMB_STRDUP(cldap_reply.netbios_domain);
00227 
00228         ads->ldap_port = LDAP_PORT;
00229         ads->ldap_ip = *interpret_addr2(srv);
00230         SAFE_FREE(srv);
00231         
00232         /* Store our site name. */
00233         sitename_store( cldap_reply.domain, cldap_reply.client_site_name );
00234 
00235         return True;
00236 }

static NTSTATUS ads_find_dc ( ADS_STRUCT ads  )  [static]

ldap.c244 行で定義されています。

参照先 add_failed_connection_entry()ads_try_connect()check_negative_conn_cache()get_sorted_dc_list()ip_service::iplp_workgroup()namecache_delete()ADS_STRUCT::realmserverADS_STRUCT::serversitename_fetch()statusADS_STRUCT::workgroup.

参照元 ads_connect().

00245 {
00246         const char *c_realm;
00247         int count, i=0;
00248         struct ip_service *ip_list;
00249         pstring realm;
00250         BOOL got_realm = False;
00251         BOOL use_own_domain = False;
00252         char *sitename;
00253         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
00254 
00255         /* if the realm and workgroup are both empty, assume they are ours */
00256 
00257         /* realm */
00258         c_realm = ads->server.realm;
00259         
00260         if ( !c_realm || !*c_realm ) {
00261                 /* special case where no realm and no workgroup means our own */
00262                 if ( !ads->server.workgroup || !*ads->server.workgroup ) {
00263                         use_own_domain = True;
00264                         c_realm = lp_realm();
00265                 }
00266         }
00267         
00268         if (c_realm && *c_realm) 
00269                 got_realm = True;
00270                    
00271         /* we need to try once with the realm name and fallback to the 
00272            netbios domain name if we fail (if netbios has not been disabled */
00273            
00274         if ( !got_realm && !lp_disable_netbios() ) {
00275                 c_realm = ads->server.workgroup;
00276                 if (!c_realm || !*c_realm) {
00277                         if ( use_own_domain )
00278                                 c_realm = lp_workgroup();
00279                 }
00280                 
00281                 if ( !c_realm || !*c_realm ) {
00282                         DEBUG(0,("ads_find_dc: no realm or workgroup!  Don't know what to do\n"));
00283                         return NT_STATUS_INVALID_PARAMETER; /* rather need MISSING_PARAMETER ... */
00284                 }
00285         }
00286         
00287         pstrcpy( realm, c_realm );
00288 
00289         sitename = sitename_fetch(realm);
00290 
00291  again:
00292 
00293         DEBUG(6,("ads_find_dc: looking for %s '%s'\n", 
00294                 (got_realm ? "realm" : "domain"), realm));
00295 
00296         status = get_sorted_dc_list(realm, sitename, &ip_list, &count, got_realm);
00297         if (!NT_STATUS_IS_OK(status)) {
00298                 /* fall back to netbios if we can */
00299                 if ( got_realm && !lp_disable_netbios() ) {
00300                         got_realm = False;
00301                         goto again;
00302                 }
00303                 
00304                 SAFE_FREE(sitename);
00305                 return status;
00306         }
00307 
00308         /* if we fail this loop, then giveup since all the IP addresses returned were dead */
00309         for ( i=0; i<count; i++ ) {
00310                 fstring server;
00311                 
00312                 fstrcpy( server, inet_ntoa(ip_list[i].ip) );
00313                 
00314                 if ( !NT_STATUS_IS_OK(check_negative_conn_cache(realm, server)) )
00315                         continue;
00316 
00317                 if (!got_realm) {
00318                         /* realm in this case is a workgroup name. We need
00319                            to ignore any IP addresses in the negative connection
00320                            cache that match ip addresses returned in the ad realm
00321                            case. It sucks that I have to reproduce the logic above... */
00322                         c_realm = ads->server.realm;
00323                         if ( !c_realm || !*c_realm ) {
00324                                 if ( !ads->server.workgroup || !*ads->server.workgroup ) {
00325                                         c_realm = lp_realm();
00326                                 }
00327                         }
00328                         if (c_realm && *c_realm &&
00329                                         !NT_STATUS_IS_OK(check_negative_conn_cache(c_realm, server))) {
00330                                 /* Ensure we add the workgroup name for this
00331                                    IP address as negative too. */
00332                                 add_failed_connection_entry( realm, server, NT_STATUS_UNSUCCESSFUL );
00333                                 continue;
00334                         }
00335                 }
00336                         
00337                 if ( ads_try_connect(ads, server) ) {
00338                         SAFE_FREE(ip_list);
00339                         SAFE_FREE(sitename);
00340                         return NT_STATUS_OK;
00341                 }
00342                 
00343                 /* keep track of failures */
00344                 add_failed_connection_entry( realm, server, NT_STATUS_UNSUCCESSFUL );
00345         }
00346 
00347         SAFE_FREE(ip_list);
00348 
00349         /* In case we failed to contact one of our closest DC on our site we
00350          * need to try to find another DC, retry with a site-less SRV DNS query
00351          * - Guenther */
00352 
00353         if (sitename) {
00354                 DEBUG(1,("ads_find_dc: failed to find a valid DC on our site (%s), "
00355                                 "trying to find another DC\n", sitename));
00356                 SAFE_FREE(sitename);
00357                 namecache_delete(realm, 0x1C);
00358                 goto again;
00359         }
00360 
00361         return NT_STATUS_NO_LOGON_SERVERS;
00362 }

ADS_STATUS ads_connect ( ADS_STRUCT ads  ) 

Connect to the LDAP server

引数:
ads Pointer to an existing ADS_STRUCT
戻り値:
status of connection

ldap.c370 行で定義されています。

参照先 ads_closest_dc()ads_current_time()ads_find_dc()ads_sasl_bind()ads_try_connect()asprintf()ADS_STRUCT::authADS_STRUCT::configADS_STRUCT::flagsglobal_mynameADS_STRUCT::kdc_serverADS_STRUCT::last_attemptADS_STRUCT::ldADS_STRUCT::ldap_ipldap_open_with_timeout()ADS_STRUCT::ldap_serverADS_STRUCT::ldap_server_namentstatusADS_STRUCT::passwordADS_STRUCT::realmsaf_store()ADS_STRUCT::serversetenv()smb_ldap_start_tls()statusADS_STRUCT::user_nameADS_STRUCT::workgroup.

参照元 ad_idmap_cached_connection_internal()ads_cached_connection()ads_current_time()ads_dc_name()ads_do_search_retry_internal()ads_domain_func_level()ads_startup_int()check_published_printers()net_ads_check_int()net_ads_password()net_update_dns_internal()nt_printer_publish().

00371 {
00372         int version = LDAP_VERSION3;
00373         ADS_STATUS status;
00374         NTSTATUS ntstatus;
00375 
00376         ads->last_attempt = time(NULL);
00377         ads->ld = NULL;
00378 
00379         /* try with a user specified server */
00380 
00381         if (ads->server.ldap_server && 
00382             ads_try_connect(ads, ads->server.ldap_server)) {
00383                 goto got_connection;
00384         }
00385 
00386         ntstatus = ads_find_dc(ads);
00387         if (NT_STATUS_IS_OK(ntstatus)) {
00388                 goto got_connection;
00389         }
00390 
00391         return ADS_ERROR_NT(ntstatus);
00392 
00393 got_connection:
00394         DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap_ip)));
00395 
00396         if (!ads->auth.user_name) {
00397                 /* Must use the userPrincipalName value here or sAMAccountName
00398                    and not servicePrincipalName; found by Guenther Deschner */
00399 
00400                 asprintf(&ads->auth.user_name, "%s$", global_myname() );
00401         }
00402 
00403         if (!ads->auth.realm) {
00404                 ads->auth.realm = SMB_STRDUP(ads->config.realm);
00405         }
00406 
00407         if (!ads->auth.kdc_server) {
00408                 ads->auth.kdc_server = SMB_STRDUP(inet_ntoa(ads->ldap_ip));
00409         }
00410 
00411 #if KRB5_DNS_HACK
00412         /* this is a really nasty hack to avoid ADS DNS problems. It needs a patch
00413            to MIT kerberos to work (tridge) */
00414         {
00415                 char *env;
00416                 asprintf(&env, "KRB5_KDC_ADDRESS_%s", ads->config.realm);
00417                 setenv(env, ads->auth.kdc_server, 1);
00418                 free(env);
00419         }
00420 #endif
00421 
00422         /* If the caller() requested no LDAP bind, then we are done */
00423         
00424         if (ads->auth.flags & ADS_AUTH_NO_BIND) {
00425                 return ADS_SUCCESS;
00426         }
00427         
00428         /* Otherwise setup the TCP LDAP session */
00429 
00430         if ( (ads->ld = ldap_open_with_timeout(ads->config.ldap_server_name, 
00431                 LDAP_PORT, lp_ldap_timeout())) == NULL )
00432         {
00433                 return ADS_ERROR(LDAP_OPERATIONS_ERROR);
00434         }
00435 
00436         /* cache the successful connection for workgroup and realm */
00437         if (ads_closest_dc(ads)) {
00438                 saf_store( ads->server.workgroup, inet_ntoa(ads->ldap_ip));
00439                 saf_store( ads->server.realm, inet_ntoa(ads->ldap_ip));
00440         }
00441 
00442         ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version);
00443 
00444         status = ADS_ERROR(smb_ldap_start_tls(ads->ld, version));
00445         if (!ADS_ERR_OK(status)) {
00446                 return status;
00447         }
00448 
00449         /* fill in the current time and offsets */
00450         
00451         status = ads_current_time( ads );
00452         if ( !ADS_ERR_OK(status) ) {
00453                 return status;
00454         }
00455 
00456         /* Now do the bind */
00457         
00458         if (ads->auth.flags & ADS_AUTH_ANON_BIND) {
00459                 return ADS_ERROR(ldap_simple_bind_s( ads->ld, NULL, NULL));
00460         }
00461 
00462         if (ads->auth.flags & ADS_AUTH_SIMPLE_BIND) {
00463                 return ADS_ERROR(ldap_simple_bind_s( ads->ld, ads->auth.user_name, ads->auth.password));
00464         }
00465 
00466         return ads_sasl_bind(ads);
00467 }

static struct berval* dup_berval ( TALLOC_CTX ctx,
const struct berval *  in_val 
) [static]

ldap.c472 行で定義されています。

参照元 ads_dup_values().

00473 {
00474         struct berval *value;
00475 
00476         if (!in_val) return NULL;
00477 
00478         value = TALLOC_ZERO_P(ctx, struct berval);
00479         if (value == NULL)
00480                 return NULL;
00481         if (in_val->bv_len == 0) return value;
00482 
00483         value->bv_len = in_val->bv_len;
00484         value->bv_val = (char *)TALLOC_MEMDUP(ctx, in_val->bv_val,
00485                                               in_val->bv_len);
00486         return value;
00487 }

static struct berval** ads_dup_values ( TALLOC_CTX ctx,
const struct berval **  in_vals 
) [static]

ldap.c492 行で定義されています。

参照先 dup_berval()values.

参照元 ads_modlist_add().

00494 {
00495         struct berval **values;
00496         int i;
00497        
00498         if (!in_vals) return NULL;
00499         for (i=0; in_vals[i]; i++)
00500                 ; /* count values */
00501         values = TALLOC_ZERO_ARRAY(ctx, struct berval *, i+1);
00502         if (!values) return NULL;
00503 
00504         for (i=0; in_vals[i]; i++) {
00505                 values[i] = dup_berval(ctx, in_vals[i]);
00506         }
00507         return values;
00508 }

static char** ads_push_strvals ( TALLOC_CTX ctx,
const char **  in_vals 
) [static]

ldap.c513 行で定義されています。

参照先 push_utf8_talloc()values.

参照元 ads_modlist_add().

00514 {
00515         char **values;
00516         int i;
00517        
00518         if (!in_vals) return NULL;
00519         for (i=0; in_vals[i]; i++)
00520                 ; /* count values */
00521         values = TALLOC_ZERO_ARRAY(ctx, char *, i+1);
00522         if (!values) return NULL;
00523 
00524         for (i=0; in_vals[i]; i++) {
00525                 push_utf8_talloc(ctx, &values[i], in_vals[i]);
00526         }
00527         return values;
00528 }

static char** ads_pull_strvals ( TALLOC_CTX ctx,
const char **  in_vals 
) [static]

ldap.c533 行で定義されています。

参照先 pull_utf8_talloc()values.

参照元 ads_process_results().

00534 {
00535         char **values;
00536         int i;
00537        
00538         if (!in_vals) return NULL;
00539         for (i=0; in_vals[i]; i++)
00540                 ; /* count values */
00541         values = TALLOC_ZERO_ARRAY(ctx, char *, i+1);
00542         if (!values) return NULL;
00543 
00544         for (i=0; in_vals[i]; i++) {
00545                 pull_utf8_talloc(ctx, &values[i], in_vals[i]);
00546         }
00547         return values;
00548 }

static ADS_STATUS ads_do_paged_search_args ( ADS_STRUCT ads,
const char *  bind_path,
int  scope,
const char *  expr,
const char **  attrs,
void *  args,
LDAPMessage **  res,
int *  count,
struct berval **  cookie 
) [static]

Do a search with paged results.

cookie must be null on the first call, and then returned on each subsequent call. It will be null again when the entire search is complete

引数:
ads connection to ads server
bind_path Base dn for the search
scope Scope of search (LDAP_SCOPE_BASE | LDAP_SCOPE_ONE | LDAP_SCOPE_SUBTREE)
expr Search expression - specified in local charset
attrs Attributes to retrieve - specified in utf8 or ascii
res ** which will contain results - free res* with ads_msgfree()
count Number of entries retrieved on this page
cookie The paged results cookie to be returned on subsequent calls
戻り値:
status of search

ldap.c564 行で定義されています。

参照先 ads_control::controlads_control::criticalctxADS_STRUCT::ldldap_search_with_timeout()push_utf8_talloc()str_list_copy()str_list_free()strequal()talloc_init()ads_control::val.

参照元 ads_do_paged_search()ads_do_search_all_args().

00570 {
00571         int rc, i, version;
00572         char *utf8_expr, *utf8_path, **search_attrs;
00573         LDAPControl PagedResults, NoReferrals, ExtendedDn, *controls[4], **rcontrols;
00574         BerElement *cookie_be = NULL;
00575         struct berval *cookie_bv= NULL;
00576         BerElement *extdn_be = NULL;
00577         struct berval *extdn_bv= NULL;
00578 
00579         TALLOC_CTX *ctx;
00580         ads_control *external_control = (ads_control *) args;
00581 
00582         *res = NULL;
00583 
00584         if (!(ctx = talloc_init("ads_do_paged_search_args")))
00585                 return ADS_ERROR(LDAP_NO_MEMORY);
00586 
00587         /* 0 means the conversion worked but the result was empty 
00588            so we only fail if it's -1.  In any case, it always 
00589            at least nulls out the dest */
00590         if ((push_utf8_talloc(ctx, &utf8_expr, expr) == (size_t)-1) ||
00591             (push_utf8_talloc(ctx, &utf8_path, bind_path) == (size_t)-1)) {
00592                 rc = LDAP_NO_MEMORY;
00593                 goto done;
00594         }
00595 
00596         if (!attrs || !(*attrs))
00597                 search_attrs = NULL;
00598         else {
00599                 /* This would be the utf8-encoded version...*/
00600                 /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */
00601                 if (!(str_list_copy(&search_attrs, attrs))) {
00602                         rc = LDAP_NO_MEMORY;
00603                         goto done;
00604                 }
00605         }
00606                 
00607                 
00608         /* Paged results only available on ldap v3 or later */
00609         ldap_get_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version);
00610         if (version < LDAP_VERSION3) {
00611                 rc =  LDAP_NOT_SUPPORTED;
00612                 goto done;
00613         }
00614 
00615         cookie_be = ber_alloc_t(LBER_USE_DER);
00616         if (*cookie) {
00617                 ber_printf(cookie_be, "{iO}", (ber_int_t) 1000, *cookie);
00618                 ber_bvfree(*cookie); /* don't need it from last time */
00619                 *cookie = NULL;
00620         } else {
00621                 ber_printf(cookie_be, "{io}", (ber_int_t) 1000, "", 0);
00622         }
00623         ber_flatten(cookie_be, &cookie_bv);
00624         PagedResults.ldctl_oid = CONST_DISCARD(char *, ADS_PAGE_CTL_OID);
00625         PagedResults.ldctl_iscritical = (char) 1;
00626         PagedResults.ldctl_value.bv_len = cookie_bv->bv_len;
00627         PagedResults.ldctl_value.bv_val = cookie_bv->bv_val;
00628 
00629         NoReferrals.ldctl_oid = CONST_DISCARD(char *, ADS_NO_REFERRALS_OID);
00630         NoReferrals.ldctl_iscritical = (char) 0;
00631         NoReferrals.ldctl_value.bv_len = 0;
00632         NoReferrals.ldctl_value.bv_val = CONST_DISCARD(char *, "");
00633 
00634         if (external_control && strequal(external_control->control, ADS_EXTENDED_DN_OID)) {
00635 
00636                 ExtendedDn.ldctl_oid = CONST_DISCARD(char *, external_control->control);
00637                 ExtendedDn.ldctl_iscritical = (char) external_control->critical;
00638 
00639                 /* win2k does not accept a ldctl_value beeing passed in */
00640 
00641                 if (external_control->val != 0) {
00642 
00643                         if ((extdn_be = ber_alloc_t(LBER_USE_DER)) == NULL ) {
00644                                 rc = LDAP_NO_MEMORY;
00645                                 goto done;
00646                         }
00647 
00648                         if ((ber_printf(extdn_be, "{i}", (ber_int_t) external_control->val)) == -1) {
00649                                 rc = LDAP_NO_MEMORY;
00650                                 goto done;
00651                         }
00652                         if ((ber_flatten(extdn_be, &extdn_bv)) == -1) {
00653                                 rc = LDAP_NO_MEMORY;
00654                                 goto done;
00655                         }
00656 
00657                         ExtendedDn.ldctl_value.bv_len = extdn_bv->bv_len;
00658                         ExtendedDn.ldctl_value.bv_val = extdn_bv->bv_val;
00659 
00660                 } else {
00661                         ExtendedDn.ldctl_value.bv_len = 0;
00662                         ExtendedDn.ldctl_value.bv_val = NULL;
00663                 }
00664 
00665                 controls[0] = &NoReferrals;
00666                 controls[1] = &PagedResults;
00667                 controls[2] = &ExtendedDn;
00668                 controls[3] = NULL;
00669 
00670         } else {
00671                 controls[0] = &NoReferrals;
00672                 controls[1] = &PagedResults;
00673                 controls[2] = NULL;
00674         }
00675 
00676         /* we need to disable referrals as the openldap libs don't
00677            handle them and paged results at the same time.  Using them
00678            together results in the result record containing the server 
00679            page control being removed from the result list (tridge/jmcd) 
00680         
00681            leaving this in despite the control that says don't generate
00682            referrals, in case the server doesn't support it (jmcd)
00683         */
00684         ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
00685 
00686         rc = ldap_search_with_timeout(ads->ld, utf8_path, scope, utf8_expr, 
00687                                       search_attrs, 0, controls,
00688                                       NULL, LDAP_NO_LIMIT,
00689                                       (LDAPMessage **)res);
00690 
00691         ber_free(cookie_be, 1);
00692         ber_bvfree(cookie_bv);
00693 
00694         if (rc) {
00695                 DEBUG(3,("ads_do_paged_search_args: ldap_search_with_timeout(%s) -> %s\n", expr,
00696                          ldap_err2string(rc)));
00697                 goto done;
00698         }
00699 
00700         rc = ldap_parse_result(ads->ld, *res, NULL, NULL, NULL,
00701                                         NULL, &rcontrols,  0);
00702 
00703         if (!rcontrols) {
00704                 goto done;
00705         }
00706 
00707         for (i=0; rcontrols[i]; i++) {
00708                 if (strcmp(ADS_PAGE_CTL_OID, rcontrols[i]->ldctl_oid) == 0) {
00709                         cookie_be = ber_init(&rcontrols[i]->ldctl_value);
00710                         ber_scanf(cookie_be,"{iO}", (ber_int_t *) count,
00711                                   &cookie_bv);
00712                         /* the berval is the cookie, but must be freed when
00713                            it is all done */
00714                         if (cookie_bv->bv_len) /* still more to do */
00715                                 *cookie=ber_bvdup(cookie_bv);
00716                         else
00717                                 *cookie=NULL;
00718                         ber_bvfree(cookie_bv);
00719                         ber_free(cookie_be, 1);
00720                         break;
00721                 }
00722         }
00723         ldap_controls_free(rcontrols);
00724 
00725 done:
00726         talloc_destroy(ctx);
00727 
00728         if (extdn_be) {
00729                 ber_free(extdn_be, 1);
00730         }
00731 
00732         if (extdn_bv) {
00733                 ber_bvfree(extdn_bv);
00734         }
00735  
00736         /* if/when we decide to utf8-encode attrs, take out this next line */
00737         str_list_free(&search_attrs);
00738 
00739         return ADS_ERROR(rc);
00740 }

static ADS_STATUS ads_do_paged_search ( ADS_STRUCT ads,
const char *  bind_path,
int  scope,
const char *  expr,
const char **  attrs,
LDAPMessage **  res,
int *  count,
struct berval **  cookie 
) [static]

ldap.c742 行で定義されています。

参照先 ads_do_paged_search_args().

参照元 ads_do_search_all_fn().

00746 {
00747         return ads_do_paged_search_args(ads, bind_path, scope, expr, attrs, NULL, res, count, cookie);
00748 }

ADS_STATUS ads_do_search_all_args ( ADS_STRUCT ads,
const char *  bind_path,
int  scope,
const char *  expr,
const char **  attrs,
void *  args,
LDAPMessage **  res 
)

Get all results for a search.

This uses ads_do_paged_search() to return all entries in a large search.

引数:
ads connection to ads server
bind_path Base dn for the search
scope Scope of search (LDAP_SCOPE_BASE | LDAP_SCOPE_ONE | LDAP_SCOPE_SUBTREE)
expr Search expression
attrs Attributes to retrieve
res ** which will contain results - free res* with ads_msgfree()
戻り値:
status of search

ldap.c762 行で定義されています。

参照先 ads_do_paged_search_args()ads_first_message()ads_next_message()status.

参照元 ads_do_search_all()ads_do_search_retry_internal().

00766 {
00767         struct berval *cookie = NULL;
00768         int count = 0;
00769         ADS_STATUS status;
00770 
00771         *res = NULL;
00772         status = ads_do_paged_search_args(ads, bind_path, scope, expr, attrs, args, res,
00773                                      &count, &cookie);
00774 
00775         if (!ADS_ERR_OK(status)) 
00776                 return status;
00777 
00778 #ifdef HAVE_LDAP_ADD_RESULT_ENTRY
00779         while (cookie) {
00780                 LDAPMessage *res2 = NULL;
00781                 ADS_STATUS status2;
00782                 LDAPMessage *msg, *next;
00783 
00784                 status2 = ads_do_paged_search_args(ads, bind_path, scope, expr, 
00785                                               attrs, args, &res2, &count, &cookie);
00786 
00787                 if (!ADS_ERR_OK(status2)) break;
00788 
00789                 /* this relies on the way that ldap_add_result_entry() works internally. I hope
00790                    that this works on all ldap libs, but I have only tested with openldap */
00791                 for (msg = ads_first_message(ads, res2); msg; msg = next) {
00792                         next = ads_next_message(ads, msg);
00793                         ldap_add_result_entry((LDAPMessage **)res, msg);
00794                 }
00795                 /* note that we do not free res2, as the memory is now
00796                    part of the main returned list */
00797         }
00798 #else
00799         DEBUG(0, ("no ldap_add_result_entry() support in LDAP libs!\n"));
00800         status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
00801 #endif
00802 
00803         return status;
00804 }

ADS_STATUS ads_do_search_all ( ADS_STRUCT ads,
const char *  bind_path,
int  scope,
const char *  expr,
const char **  attrs,
LDAPMessage **  res 
)

ldap.c806 行で定義されています。

参照先 ads_do_search_all_args().

参照元 ads_get_gpo()gpo_password_policy()net_ads_dn()net_ads_gpo_apply()net_ads_gpo_list()net_ads_gpo_refresh()net_ads_search().

00809 {
00810         return ads_do_search_all_args(ads, bind_path, scope, expr, attrs, NULL, res);
00811 }

ADS_STATUS ads_do_search_all_fn ( ADS_STRUCT ads,
const char *  bind_path,
int  scope,
const char *  expr,
const char **  attrs,
BOOL(*)(char *, void **, void *)  fn,
void *  data_area 
)

Run a function on all results for a search.

Uses ads_do_paged_search() and runs the function as each page is returned, using ads_process_results()

引数:
ads connection to ads server
bind_path Base dn for the search
scope Scope of search (LDAP_SCOPE_BASE | LDAP_SCOPE_ONE | LDAP_SCOPE_SUBTREE)
expr Search expression - specified in local charset
attrs Attributes to retrieve - specified in UTF-8 or ascii
fn Function which takes attr name, values list, and data_area
data_area Pointer which is passed to function on each call
戻り値:
status of search

ldap.c825 行で定義されています。

参照先 ads_do_paged_search()ads_msgfree()ads_process_results()fnstatus.

参照元 net_ads_group()net_ads_user().

00829 {
00830         struct berval *cookie = NULL;
00831         int count = 0;
00832         ADS_STATUS status;
00833         LDAPMessage *res;
00834 
00835         status = ads_do_paged_search(ads, bind_path, scope, expr, attrs, &res,
00836                                      &count, &cookie);
00837 
00838         if (!ADS_ERR_OK(status)) return status;
00839 
00840         ads_process_results(ads, res, fn, data_area);
00841         ads_msgfree(ads, res);
00842 
00843         while (cookie) {
00844                 status = ads_do_paged_search(ads, bind_path, scope, expr, attrs,
00845                                              &res, &count, &cookie);
00846 
00847                 if (!ADS_ERR_OK(status)) break;
00848                 
00849                 ads_process_results(ads, res, fn, data_area);
00850                 ads_msgfree(ads, res);
00851         }
00852 
00853         return status;
00854 }

ADS_STATUS ads_do_search ( ADS_STRUCT ads,
const char *  bind_path,
int  scope,
const char *  expr,
const char **  attrs,
LDAPMessage **  res 
)

Do a search with a timeout.

引数:
ads connection to ads server
bind_path Base dn for the search
scope Scope of search (LDAP_SCOPE_BASE | LDAP_SCOPE_ONE | LDAP_SCOPE_SUBTREE)
expr Search expression
attrs Attributes to retrieve
res ** which will contain results - free res* with ads_msgfree()
戻り値:
status of search

ldap.c866 行で定義されています。

参照先 ctxADS_STRUCT::ldldap_search_with_timeout()push_utf8_talloc()str_list_copy()str_list_free()talloc_init().

参照元 ads_current_time()ads_do_search_retry_internal()ads_domain_func_level()ads_sasl_bind()ads_schema_path()ads_search()ads_search_dn()ads_site_dn()ads_site_dn_for_machine()ads_upn_suffixes()net_update_dns_internal().

00869 {
00870         int rc;
00871         char *utf8_expr, *utf8_path, **search_attrs = NULL;
00872         TALLOC_CTX *ctx;
00873 
00874         *res = NULL;
00875         if (!(ctx = talloc_init("ads_do_search"))) {
00876                 DEBUG(1,("ads_do_search: talloc_init() failed!"));
00877                 return ADS_ERROR(LDAP_NO_MEMORY);
00878         }
00879 
00880         /* 0 means the conversion worked but the result was empty 
00881            so we only fail if it's negative.  In any case, it always 
00882            at least nulls out the dest */
00883         if ((push_utf8_talloc(ctx, &utf8_expr, expr) == (size_t)-1) ||
00884             (push_utf8_talloc(ctx, &utf8_path, bind_path) == (size_t)-1)) {
00885                 DEBUG(1,("ads_do_search: push_utf8_talloc() failed!"));
00886                 rc = LDAP_NO_MEMORY;
00887                 goto done;
00888         }
00889 
00890         if (!attrs || !(*attrs))
00891                 search_attrs = NULL;
00892         else {
00893                 /* This would be the utf8-encoded version...*/
00894                 /* if (!(search_attrs = ads_push_strvals(ctx, attrs)))  */
00895                 if (!(str_list_copy(&search_attrs, attrs)))
00896                 {
00897                         DEBUG(1,("ads_do_search: str_list_copy() failed!"));
00898                         rc = LDAP_NO_MEMORY;
00899                         goto done;
00900                 }
00901         }
00902 
00903         /* see the note in ads_do_paged_search - we *must* disable referrals */
00904         ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
00905 
00906         rc = ldap_search_with_timeout(ads->ld, utf8_path, scope, utf8_expr,
00907                                       search_attrs, 0, NULL, NULL, 
00908                                       LDAP_NO_LIMIT,
00909                                       (LDAPMessage **)res);
00910 
00911         if (rc == LDAP_SIZELIMIT_EXCEEDED) {
00912                 DEBUG(3,("Warning! sizelimit exceeded in ldap. Truncating.\n"));
00913                 rc = 0;
00914         }
00915 
00916  done:
00917         talloc_destroy(ctx);
00918         /* if/when we decide to utf8-encode attrs, take out this next line */
00919         str_list_free(&search_attrs);
00920         return ADS_ERROR(rc);
00921 }

ADS_STATUS ads_search ( ADS_STRUCT ads,
LDAPMessage **  res,
const char *  expr,
const char **  attrs 
)

Do a general ADS search

引数:
ads connection to ads server
res ** which will contain results - free res* with ads_msgfree()
expr Search expression
attrs Attributes to retrieve
戻り値:
status of search

ldap.c930 行で定義されています。

参照先 ads_do_search()ADS_STRUCT::bind_pathADS_STRUCT::config.

参照元 ads_find_machine_acct()ads_find_printer_on_server()ads_find_printers()ads_find_user_acct()ads_get_kvno()ads_user_info().

00932 {
00933         return ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, 
00934                              expr, attrs, res);
00935 }

ADS_STATUS ads_search_dn ( ADS_STRUCT ads,
LDAPMessage **  res,
const char *  dn,
const char **  attrs 
)

Do a search on a specific DistinguishedName

引数:
ads connection to ads server
res ** which will contain results - free res* with ads_msgfree()
dn DistinguishName to search
attrs Attributes to retrieve
戻り値:
status of search

ldap.c945 行で定義されています。

参照先 ads_do_search().

参照元 ads_add_gpo_link()ads_default_ou_string()ads_delete_gpo_link()ads_get_gpo()ads_get_gpo_link()ads_upn_suffixes()net_precreate_machine_acct()nt_printer_publish_ads().

00947 {
00948         return ads_do_search(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)",
00949                              attrs, res);
00950 }

void ads_msgfree ( ADS_STRUCT ads,
LDAPMessage *  msg 
)

Free up memory from a ads_search

引数:
ads connection to ads server
msg Search results to free

ldap.c957 行で定義されています。

参照元 ads_add_gpo_link()ads_add_service_principal_name()ads_clear_service_principal_names()ads_create_machine_acct()ads_current_time()ads_default_ou_string()ads_delete_gpo_link()ads_do_search_all_fn()ads_do_search_retry_internal()ads_domain_func_level()ads_domain_sid()ads_find_printer_on_server()ads_get_attrname_by_oid()ads_get_attrnames_by_oids()ads_get_dnshostname()ads_get_gpo()ads_get_gpo_link()ads_get_kvno()ads_get_samaccountname()ads_get_upn()ads_group_add()ads_group_delete()ads_join_realm()ads_schema_path()ads_site_dn()ads_site_dn_for_machine()ads_upn_suffixes()ads_user_add()ads_user_delete()ads_user_info()ads_USN()dn_lookup()enum_dom_groups()gpo_password_policy()idmap_ad_sids_to_unixids()lookup_groupmem()lookup_usergroups()lookup_usergroups_member()lookup_usergroups_memberof()net_ads_dn()net_ads_gpo_apply()net_ads_gpo_list()net_ads_gpo_refresh()net_ads_printer_info()net_ads_printer_remove()net_ads_printer_search()net_ads_search()net_ads_sid()net_derive_salting_principal()net_precreate_machine_acct()net_set_machine_spn()net_set_machine_upn()net_set_os_attributes()net_update_dns_internal()nt_printer_publish_ads()nt_printer_unpublish_ads()query_user()query_user_list().

00958 {
00959         if (!msg) return;
00960         ldap_msgfree(msg);
00961 }

void ads_memfree ( ADS_STRUCT ads,
void *  mem 
)

Free up memory from various ads requests

引数:
ads connection to ads server
mem Area to free

ldap.c968 行で定義されています。

参照元 ads_add_service_principal_name()ads_clear_service_principal_names()ads_default_ou_string()ads_get_gpo()ads_get_kvno()ads_group_delete()ads_leave_realm()ads_site_dn_for_machine()ads_user_add()ads_user_delete()gpo_password_policy()lookup_usergroups()net_ads_gpo_apply()net_ads_gpo_list()net_ads_gpo_refresh()net_ads_printer_remove()net_set_machine_spn()net_set_machine_upn()net_set_os_attributes()nt_printer_unpublish_ads().

00969 {
00970         SAFE_FREE(mem);
00971 }

char* ads_get_dn ( ADS_STRUCT ads,
LDAPMessage *  msg 
)

Get a dn from search results

引数:
ads connection to ads server
msg Search result
戻り値:
dn string

ldap.c979 行で定義されています。

参照先 ADS_STRUCT::ldpull_utf8_allocate().

参照元 ads_add_service_principal_name()ads_clear_service_principal_names()ads_default_ou_string()ads_get_gpo()ads_get_kvno()ads_group_delete()ads_leave_realm()ads_parse_gpo()ads_site_dn_for_machine()ads_user_add()ads_user_delete()gpo_password_policy()lookup_usergroups()net_ads_gpo_apply()net_ads_gpo_list()net_ads_gpo_refresh()net_ads_printer_remove()net_set_machine_spn()net_set_machine_upn()net_set_os_attributes()nt_printer_unpublish_ads().

00980 {
00981         char *utf8_dn, *unix_dn;
00982 
00983         utf8_dn = ldap_get_dn(ads->ld, msg);
00984 
00985         if (!utf8_dn) {
00986                 DEBUG (5, ("ads_get_dn: ldap_get_dn failed\n"));
00987                 return NULL;
00988         }
00989 
00990         if (pull_utf8_allocate(&unix_dn, utf8_dn) == (size_t)-1) {
00991                 DEBUG(0,("ads_get_dn: string conversion failure utf8 [%s]\n",
00992                         utf8_dn ));
00993                 return NULL;
00994         }
00995         ldap_memfree(utf8_dn);
00996         return unix_dn;
00997 }

char* ads_parent_dn ( const char *  dn  ) 

Get the parent from a dn

引数:
dn the dn to return the parent from
戻り値:
parent dn string

ldap.c1004 行で定義されています。

参照元 ads_get_gpo_list()ads_site_dn()ads_site_dn_for_machine().

01005 {
01006         char *p;
01007 
01008         if (dn == NULL) {
01009                 return NULL;
01010         }
01011 
01012         p = strchr(dn, ',');
01013 
01014         if (p == NULL) {
01015                 return NULL;
01016         }
01017 
01018         return p+1;
01019 }

ADS_STATUS ads_find_machine_acct ( ADS_STRUCT ads,
LDAPMessage **  res,
const char *  machine 
)

Find a machine account given a hostname

引数:
ads connection to ads server
res ** which will contain results - free res* with ads_msgfree()
host Hostname to search for
戻り値:
status of search

ldap.c1028 行で定義されています。

参照先 ads_search()asprintf()status.

参照元 ads_add_service_principal_name()ads_clear_service_principal_names()ads_find_printer_on_server()ads_get_dnshostname()ads_get_samaccountname()ads_get_upn()ads_join_realm()ads_leave_realm()net_ads_printer_publish()net_ads_status()net_derive_salting_principal()net_set_machine_spn()net_set_machine_upn()net_set_os_attributes()nt_printer_publish_ads().

01030 {
01031         ADS_STATUS status;
01032         char *expr;
01033         const char *attrs[] = {"*", "nTSecurityDescriptor", NULL};
01034 
01035         *res = NULL;
01036 
01037         /* the easiest way to find a machine account anywhere in the tree
01038            is to look for hostname$ */
01039         if (asprintf(&expr, "(samAccountName=%s$)", machine) == -1) {
01040                 DEBUG(1, ("asprintf failed!\n"));
01041                 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
01042         }
01043         
01044         status = ads_search(ads, res, expr, attrs);
01045         SAFE_FREE(expr);
01046         return status;
01047 }

ADS_MODLIST ads_init_mods ( TALLOC_CTX ctx  ) 

Initialize a list of mods to be used in a modify request

引数:
ctx An initialized TALLOC_CTX
戻り値:
allocated ADS_MODLIST

ldap.c1054 行で定義されています。

参照元 ads_add_gpo_link()ads_add_group_acct()ads_add_service_principal_name()ads_add_user_acct()ads_clear_service_principal_names()ads_create_machine_acct()ads_delete_gpo_link()net_ads_printer_publish()net_set_machine_spn()net_set_machine_upn()net_set_os_attributes()nt_printer_publish_ads().

01055 {
01056 #define ADS_MODLIST_ALLOC_SIZE 10
01057         LDAPMod **mods;
01058         
01059         if ((mods = TALLOC_ZERO_ARRAY(ctx, LDAPMod *, ADS_MODLIST_ALLOC_SIZE + 1)))
01060                 /* -1 is safety to make sure we don't go over the end.
01061                    need to reset it to NULL before doing ldap modify */
01062                 mods[ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1;
01063         
01064         return (ADS_MODLIST)mods;
01065 }

static ADS_STATUS ads_modlist_add ( TALLOC_CTX ctx,
ADS_MODLIST mods,
int  mod_op,
const char *  name,
const void *  _invals 
) [static]

ldap.c1071 行で定義されています。

参照先 ads_dup_values()ads_push_strvals()LDAP_SUCCESStalloc_strdup().

参照元 ads_add_strlist()ads_mod_ber()ads_mod_str()ads_mod_strlist().

01074 {
01075         const void **invals = (const void **)_invals;
01076         int curmod;
01077         LDAPMod **modlist = (LDAPMod **) *mods;
01078         struct berval **ber_values = NULL;
01079         char **char_values = NULL;
01080 
01081         if (!invals) {
01082                 mod_op = LDAP_MOD_DELETE;
01083         } else {
01084                 if (mod_op & LDAP_MOD_BVALUES)
01085                         ber_values = ads_dup_values(ctx, 
01086                                                 (const struct berval **)invals);
01087                 else
01088                         char_values = ads_push_strvals(ctx, 
01089                                                   (const char **) invals);
01090         }
01091 
01092         /* find the first empty slot */
01093         for (curmod=0; modlist[curmod] && modlist[curmod] != (LDAPMod *) -1;
01094              curmod++);
01095         if (modlist[curmod] == (LDAPMod *) -1) {
01096                 if (!(modlist = TALLOC_REALLOC_ARRAY(ctx, modlist, LDAPMod *,
01097                                 curmod+ADS_MODLIST_ALLOC_SIZE+1)))
01098                         return ADS_ERROR(LDAP_NO_MEMORY);
01099                 memset(&modlist[curmod], 0, 
01100                        ADS_MODLIST_ALLOC_SIZE*sizeof(LDAPMod *));
01101                 modlist[curmod+ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1;
01102                 *mods = (ADS_MODLIST)modlist;
01103         }
01104                 
01105         if (!(modlist[curmod] = TALLOC_ZERO_P(ctx, LDAPMod)))
01106                 return ADS_ERROR(LDAP_NO_MEMORY);
01107         modlist[curmod]->mod_type = talloc_strdup(ctx, name);
01108         if (mod_op & LDAP_MOD_BVALUES) {
01109                 modlist[curmod]->mod_bvalues = ber_values;
01110         } else if (mod_op & LDAP_MOD_DELETE) {
01111                 modlist[curmod]->mod_values = NULL;
01112         } else {
01113                 modlist[curmod]->mod_values = char_values;
01114         }
01115 
01116         modlist[curmod]->mod_op = mod_op;
01117         return ADS_ERROR(LDAP_SUCCESS);
01118 }

ADS_STATUS ads_mod_str ( TALLOC_CTX ctx,
ADS_MODLIST mods,
const char *  name,
const char *  val 
)

Add a single string value to a mod list

引数:
ctx An initialized TALLOC_CTX
mods An initialized ADS_MODLIST
name The attribute name to add
val The value to add - NULL means DELETE
戻り値:
ADS STATUS indicating success of add

ldap.c1128 行で定義されています。

参照先 ads_modlist_add()values.

参照元 ads_add_gpo_link()ads_add_group_acct()ads_add_printer_entry()ads_add_user_acct()ads_create_machine_acct()ads_delete_gpo_link()get_remote_printer_publishing_data()map_bool()map_dword()map_sz()net_set_machine_spn()net_set_machine_upn()net_set_os_attributes()nt_printer_publish_ads().

01130 {
01131         const char *values[2];
01132 
01133         values[0] = val;
01134         values[1] = NULL;
01135 
01136         if (!val)
01137                 return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL);
01138         return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, values);
01139 }

ADS_STATUS ads_mod_strlist ( TALLOC_CTX ctx,
ADS_MODLIST mods,
const char *  name,
const char **  vals 
)

Add an array of string values to a mod list

引数:
ctx An initialized TALLOC_CTX
mods An initialized ADS_MODLIST
name The attribute name to add
vals The array of string values to add - NULL means DELETE
戻り値:
ADS STATUS indicating success of add

ldap.c1149 行で定義されています。

参照先 ads_modlist_add().

参照元 ads_add_group_acct()ads_add_user_acct()ads_clear_service_principal_names()ads_create_machine_acct()map_multi_sz()net_set_machine_spn().

01151 {
01152         if (!vals)
01153                 return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL);
01154         return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, 
01155                                name, (const void **) vals);
01156 }

static ADS_STATUS ads_mod_ber ( TALLOC_CTX ctx,
ADS_MODLIST mods,
const char *  name,
const struct berval *  val 
) [static]

Add a single ber-encoded value to a mod list

引数:
ctx An initialized TALLOC_CTX
mods An initialized ADS_MODLIST
name The attribute name to add
val The value to add - NULL means DELETE
戻り値:
ADS STATUS indicating success of add

ldap.c1167 行で定義されています。

参照先 ads_modlist_add()values.

01169 {
01170         const struct berval *values[2];
01171 
01172         values[0] = val;
01173         values[1] = NULL;
01174         if (!val)
01175                 return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL);
01176         return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE|LDAP_MOD_BVALUES,
01177                                name, (const void **) values);
01178 }

ADS_STATUS ads_gen_mod ( ADS_STRUCT ads,
const char *  mod_dn,
ADS_MODLIST  mods 
)

Perform an ldap modify

引数:
ads connection to ads server
mod_dn DistinguishedName to modify
mods list of modifications to perform
戻り値:
status of modify

ldap.c1188 行で定義されています。

参照先 ADS_STRUCT::ldpush_utf8_allocate().

参照元 ads_add_gpo_link()ads_add_service_principal_name()ads_clear_service_principal_names()ads_delete_gpo_link()ads_mod_printer_entry()net_set_machine_spn()net_set_machine_upn()net_set_os_attributes().

01189 {
01190         int ret,i;
01191         char *utf8_dn = NULL;
01192         /* 
01193            this control is needed to modify that contains a currently 
01194            non-existent attribute (but allowable for the object) to run
01195         */
01196         LDAPControl PermitModify = {
01197                 CONST_DISCARD(char *, ADS_PERMIT_MODIFY_OID),
01198                 {0, NULL},
01199                 (char) 1};
01200         LDAPControl *controls[2];
01201 
01202         controls[0] = &PermitModify;
01203         controls[1] = NULL;
01204 
01205         if (push_utf8_allocate(&utf8_dn, mod_dn) == -1) {
01206                 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
01207         }
01208 
01209         /* find the end of the list, marked by NULL or -1 */
01210         for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++);
01211         /* make sure the end of the list is NULL */
01212         mods[i] = NULL;
01213         ret = ldap_modify_ext_s(ads->ld, utf8_dn,
01214                                 (LDAPMod **) mods, controls, NULL);
01215         SAFE_FREE(utf8_dn);
01216         return ADS_ERROR(ret);
01217 }

ADS_STATUS ads_gen_add ( ADS_STRUCT ads,
const char *  new_dn,
ADS_MODLIST  mods 
)

Perform an ldap add

引数:
ads connection to ads server
new_dn DistinguishedName to add
mods list of attributes and values for DN
戻り値:
status of add

ldap.c1226 行で定義されています。

参照先 ADS_STRUCT::ldpush_utf8_allocate().

参照元 ads_add_group_acct()ads_add_printer_entry()ads_add_user_acct()ads_create_machine_acct().

01227 {
01228         int ret, i;
01229         char *utf8_dn = NULL;
01230 
01231         if (push_utf8_allocate(&utf8_dn, new_dn) == -1) {
01232                 DEBUG(1, ("ads_gen_add: push_utf8_allocate failed!"));
01233                 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
01234         }
01235         
01236         /* find the end of the list, marked by NULL or -1 */
01237         for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++);
01238         /* make sure the end of the list is NULL */
01239         mods[i] = NULL;
01240 
01241         ret = ldap_add_s(ads->ld, utf8_dn, (LDAPMod**)mods);
01242         SAFE_FREE(utf8_dn);
01243         return ADS_ERROR(ret);
01244 }

ADS_STATUS ads_del_dn ( ADS_STRUCT ads,
char *  del_dn 
)

Delete a DistinguishedName

引数:
ads connection to ads server
new_dn DistinguishedName to delete
戻り値:
status of delete

ldap.c1252 行で定義されています。

参照先 ADS_STRUCT::ldpush_utf8_allocate().

参照元 ads_group_delete()ads_leave_realm()ads_user_add()ads_user_delete()net_ads_printer_remove()nt_printer_unpublish_ads().

01253 {
01254         int ret;
01255         char *utf8_dn = NULL;
01256         if (push_utf8_allocate(&utf8_dn, del_dn) == -1) {
01257                 DEBUG(1, ("ads_del_dn: push_utf8_allocate failed!"));
01258                 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
01259         }
01260         
01261         ret = ldap_delete_s(ads->ld, utf8_dn);
01262         SAFE_FREE(utf8_dn);
01263         return ADS_ERROR(ret);
01264 }

char* ads_ou_string ( ADS_STRUCT ads,
const char *  org_unit 
)

Build an org unit string if org unit is Computers or blank then assume a container, otherwise assume a / separated list of organisational units.

jmcd: '\' is now used for escapes so certain chars can be in the ou (e.g. #)

引数:
ads connection to ads server
org_unit Organizational unit
戻り値:
org unit string - caller must free

ldap.c1275 行で定義されています。

参照先 ads_build_path()ads_default_ou_string()strequal().

参照元 net_precreate_machine_acct().

01276 {
01277         char *ret = NULL;
01278 
01279         if (!org_unit || !*org_unit) {
01280 
01281                 ret = ads_default_ou_string(ads, WELL_KNOWN_GUID_COMPUTERS);
01282 
01283                 /* samba4 might not yet respond to a wellknownobject-query */
01284                 return ret ? ret : SMB_STRDUP("cn=Computers");
01285         }
01286         
01287         if (strequal(org_unit, "Computers")) {
01288                 return SMB_STRDUP("cn=Computers");
01289         }
01290 
01291         /* jmcd: removed "\\" from the separation chars, because it is
01292            needed as an escape for chars like '#' which are valid in an
01293            OU name */
01294         return ads_build_path(org_unit, "/", "ou=", 1);
01295 }

char* ads_default_ou_string ( ADS_STRUCT ads,
const char *  wknguid 
)

Get a org unit string for a well-known GUID

引数:
ads connection to ads server
wknguid Well known GUID
戻り値:
org unit string - caller must free

ldap.c1303 行で定義されています。

参照先 ads_count_replies()ads_get_dn()ads_memfree()ads_msgfree()ads_search_dn()asprintf()ADS_STRUCT::bind_pathADS_STRUCT::configstatus.

参照元 ads_group_add()ads_ou_string()ads_user_add().

01304 {
01305         ADS_STATUS status;
01306         LDAPMessage *res = NULL;
01307         char *base, *wkn_dn = NULL, *ret = NULL, **wkn_dn_exp = NULL,
01308                 **bind_dn_exp = NULL;
01309         const char *attrs[] = {"distinguishedName", NULL};
01310         int new_ln, wkn_ln, bind_ln, i;
01311 
01312         if (wknguid == NULL) {
01313                 return NULL;
01314         }
01315 
01316         if (asprintf(&base, "<WKGUID=%s,%s>", wknguid, ads->config.bind_path ) == -1) {
01317                 DEBUG(1, ("asprintf failed!\n"));
01318                 return NULL;
01319         }
01320 
01321         status = ads_search_dn(ads, &res, base, attrs);
01322         if (!ADS_ERR_OK(status)) {
01323                 DEBUG(1,("Failed while searching for: %s\n", base));
01324                 goto out;
01325         }
01326 
01327         if (ads_count_replies(ads, res) != 1) {
01328                 goto out;
01329         }
01330 
01331         /* substitute the bind-path from the well-known-guid-search result */
01332         wkn_dn = ads_get_dn(ads, res);
01333         if (!wkn_dn) {
01334                 goto out;
01335         }
01336 
01337         wkn_dn_exp = ldap_explode_dn(wkn_dn, 0);
01338         if (!wkn_dn_exp) {
01339                 goto out;
01340         }
01341 
01342         bind_dn_exp = ldap_explode_dn(ads->config.bind_path, 0);
01343         if (!bind_dn_exp) {
01344                 goto out;
01345         }
01346 
01347         for (wkn_ln=0; wkn_dn_exp[wkn_ln]; wkn_ln++)
01348                 ;
01349         for (bind_ln=0; bind_dn_exp[bind_ln]; bind_ln++)
01350                 ;
01351 
01352         new_ln = wkn_ln - bind_ln;
01353 
01354         ret = SMB_STRDUP(wkn_dn_exp[0]);
01355         if (!ret) {
01356                 goto out;
01357         }
01358 
01359         for (i=1; i < new_ln; i++) {
01360                 char *s = NULL;
01361                 
01362                 if (asprintf(&s, "%s,%s", ret, wkn_dn_exp[i]) == -1) {
01363                         SAFE_FREE(ret);
01364                         goto out;
01365                 }
01366 
01367                 SAFE_FREE(ret);
01368                 ret = SMB_STRDUP(s);
01369                 free(s);
01370                 if (!ret) {
01371                         goto out;
01372                 }
01373         }
01374 
01375  out:
01376         SAFE_FREE(base);
01377         ads_msgfree(ads, res);
01378         ads_memfree(ads, wkn_dn);
01379         if (wkn_dn_exp) {
01380                 ldap_value_free(wkn_dn_exp);
01381         }
01382         if (bind_dn_exp) {
01383                 ldap_value_free(bind_dn_exp);
01384         }
01385 
01386         return ret;
01387 }

ADS_STATUS ads_add_strlist ( TALLOC_CTX ctx,
ADS_MODLIST mods,
const char *  name,
const char **  vals 
)

Adds (appends) an item to an attribute array, rather then replacing the whole list

引数:
ctx An initialized TALLOC_CTX
mods An initialized ADS_MODLIST
name name of the ldap attribute to append to
vals an array of values to add
戻り値:
status of addition

ldap.c1399 行で定義されています。

参照先 ads_modlist_add().

参照元 ads_add_service_principal_name().

01401 {
01402         return ads_modlist_add(ctx, mods, LDAP_MOD_ADD, name,
01403                                (const void *) vals);
01404 }

uint32 ads_get_kvno ( ADS_STRUCT ads,
const char *  machine_name 
)

Determines the computer account's current KVNO via an LDAP lookup

引数:
ads An initialized ADS_STRUCT
machine_name the NetBIOS name of the computer, which is used to identify the computer account.
戻り値:
the kvno for the computer account, or -1 in case of a failure.

ldap.c1413 行で定義されています。

参照先 ads_count_replies()ads_get_dn()ads_memfree()ads_msgfree()ads_pull_uint32()ads_search()asprintf()LDAP_SUCCESS.

参照元 ads_keytab_add_entry()ads_keytab_create_default()ads_keytab_flush().

01414 {
01415         LDAPMessage *res = NULL;
01416         uint32 kvno = (uint32)-1;      /* -1 indicates a failure */
01417         char *filter;
01418         const char *attrs[] = {"msDS-KeyVersionNumber", NULL};
01419         char *dn_string = NULL;
01420         ADS_STATUS ret = ADS_ERROR(LDAP_SUCCESS);
01421 
01422         DEBUG(5,("ads_get_kvno: Searching for host %s\n", machine_name));
01423         if (asprintf(&filter, "(samAccountName=%s$)", machine_name) == -1) {
01424                 return kvno;
01425         }
01426         ret = ads_search(ads, &res, filter, attrs);
01427         SAFE_FREE(filter);
01428         if (!ADS_ERR_OK(ret) && ads_count_replies(ads, res)) {
01429                 DEBUG(1,("ads_get_kvno: Computer Account For %s not found.\n", machine_name));
01430                 ads_msgfree(ads, res);
01431                 return kvno;
01432         }
01433 
01434         dn_string = ads_get_dn(ads, res);
01435         if (!dn_string) {
01436                 DEBUG(0,("ads_get_kvno: out of memory.\n"));
01437                 ads_msgfree(ads, res);
01438                 return kvno;
01439         }
01440         DEBUG(5,("ads_get_kvno: Using: %s\n", dn_string));
01441         ads_memfree(ads, dn_string);
01442 
01443         /* ---------------------------------------------------------
01444          * 0 is returned as a default KVNO from this point on...
01445          * This is done because Windows 2000 does not support key
01446          * version numbers.  Chances are that a failure in the next
01447          * step is simply due to Windows 2000 being used for a
01448          * domain controller. */
01449         kvno = 0;
01450 
01451         if (!ads_pull_uint32(ads, res, "msDS-KeyVersionNumber", &kvno)) {
01452                 DEBUG(3,("ads_get_kvno: Error Determining KVNO!\n"));
01453                 DEBUG(3,("ads_get_kvno: Windows 2000 does not support KVNO's, so this may be normal.\n"));
01454                 ads_msgfree(ads, res);
01455                 return kvno;
01456         }
01457 
01458         /* Success */
01459         DEBUG(5,("ads_get_kvno: Looked Up KVNO of: %d\n", kvno));
01460         ads_msgfree(ads, res);
01461         return kvno;
01462 }

ADS_STATUS ads_clear_service_principal_names ( ADS_STRUCT ads,
const char *  machine_name 
)

This clears out all registered spn's for a given hostname

引数:
ads An initilaized ADS_STRUCT
machine_name the NetBIOS name of the computer.
戻り値:
0 upon success, non-zero otherwise.

ldap.c1471 行で定義されています。

参照先 ads_count_replies()ads_find_machine_acct()ads_gen_mod()ads_get_dn()ads_init_mods()ads_memfree()ads_mod_strlist()ads_msgfree()ctxLDAP_SUCCESStalloc_init().

参照元 ads_keytab_flush().

01472 {
01473         TALLOC_CTX *ctx;
01474         LDAPMessage *res = NULL;
01475         ADS_MODLIST mods;
01476         const char *servicePrincipalName[1] = {NULL};
01477         ADS_STATUS ret = ADS_ERROR(LDAP_SUCCESS);
01478         char *dn_string = NULL;
01479 
01480         ret = ads_find_machine_acct(ads, &res, machine_name);
01481         if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) {
01482                 DEBUG(5,("ads_clear_service_principal_names: WARNING: Host Account for %s not found... skipping operation.\n", machine_name));
01483                 DEBUG(5,("ads_clear_service_principal_names: WARNING: Service Principals for %s have NOT been cleared.\n", machine_name));
01484                 ads_msgfree(ads, res);
01485                 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
01486         }
01487 
01488         DEBUG(5,("ads_clear_service_principal_names: Host account for %s found\n", machine_name));
01489         ctx = talloc_init("ads_clear_service_principal_names");
01490         if (!ctx) {
01491                 ads_msgfree(ads, res);
01492                 return ADS_ERROR(LDAP_NO_MEMORY);
01493         }
01494 
01495         if (!(mods = ads_init_mods(ctx))) {
01496                 talloc_destroy(ctx);
01497                 ads_msgfree(ads, res);
01498                 return ADS_ERROR(LDAP_NO_MEMORY);
01499         }
01500         ret = ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName);
01501         if (!ADS_ERR_OK(ret)) {
01502                 DEBUG(1,("ads_clear_service_principal_names: Error creating strlist.\n"));
01503                 ads_msgfree(ads, res);
01504                 talloc_destroy(ctx);
01505                 return ret;
01506         }
01507         dn_string = ads_get_dn(ads, res);
01508         if (!dn_string) {
01509                 talloc_destroy(ctx);
01510                 ads_msgfree(ads, res);
01511                 return ADS_ERROR(LDAP_NO_MEMORY);
01512         }
01513         ret = ads_gen_mod(ads, dn_string, mods);
01514         ads_memfree(ads,dn_string);
01515         if (!ADS_ERR_OK(ret)) {
01516                 DEBUG(1,("ads_clear_service_principal_names: Error: Updating Service Principals for machine %s in LDAP\n",
01517                         machine_name));
01518                 ads_msgfree(ads, res);
01519                 talloc_destroy(ctx);
01520                 return ret;
01521         }
01522 
01523         ads_msgfree(ads, res);
01524         talloc_destroy(ctx);
01525         return ret;
01526 }

ADS_STATUS ads_add_service_principal_name ( ADS_STRUCT ads,
const char *  machine_name,
const char *  my_fqdn,
const char *  spn 
)

This adds a service principal name to an existing computer account (found by hostname) in AD.

引数:
ads An initialized ADS_STRUCT
machine_name the NetBIOS name of the computer, which is used to identify the computer account.
my_fqdn The fully qualified DNS name of the machine
spn A string of the service principal to add, i.e. 'host'
戻り値:
0 upon sucess, or non-zero if a failure occurs

ldap.c1538 行で定義されています。

参照先 ads_add_strlist()ads_count_replies()ads_find_machine_acct()ads_gen_mod()ads_get_dn()ads_init_mods()ads_memfree()ads_msgfree()ADS_STRUCT::configctxADS_STRUCT::realmstrlower_m()strupper_m()talloc_asprintf()talloc_init().

参照元 ads_keytab_add_entry().

01540 {
01541         ADS_STATUS ret;
01542         TALLOC_CTX *ctx;
01543         LDAPMessage *res = NULL;
01544         char *psp1, *psp2;
01545         ADS_MODLIST mods;
01546         char *dn_string = NULL;
01547         const char *servicePrincipalName[3] = {NULL, NULL, NULL};
01548 
01549         ret = ads_find_machine_acct(ads, &res, machine_name);
01550         if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) {
01551                 DEBUG(1,("ads_add_service_principal_name: WARNING: Host Account for %s not found... skipping operation.\n",
01552                         machine_name));
01553                 DEBUG(1,("ads_add_service_principal_name: WARNING: Service Principal '%s/%s@%s' has NOT been added.\n",
01554                         spn, machine_name, ads->config.realm));
01555                 ads_msgfree(ads, res);
01556                 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
01557         }
01558 
01559         DEBUG(1,("ads_add_service_principal_name: Host account for %s found\n", machine_name));
01560         if (!(ctx = talloc_init("ads_add_service_principal_name"))) {
01561                 ads_msgfree(ads, res);
01562                 return ADS_ERROR(LDAP_NO_MEMORY);
01563         }
01564 
01565         /* add short name spn */
01566         
01567         if ( (psp1 = talloc_asprintf(ctx, "%s/%s", spn, machine_name)) == NULL ) {
01568                 talloc_destroy(ctx);
01569                 ads_msgfree(ads, res);
01570                 return ADS_ERROR(LDAP_NO_MEMORY);
01571         }
01572         strupper_m(psp1);
01573         strlower_m(&psp1[strlen(spn)]);
01574         servicePrincipalName[0] = psp1;
01575         
01576         DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", 
01577                 psp1, machine_name));
01578 
01579 
01580         /* add fully qualified spn */
01581         
01582         if ( (psp2 = talloc_asprintf(ctx, "%s/%s", spn, my_fqdn)) == NULL ) {
01583                 ret = ADS_ERROR(LDAP_NO_MEMORY);
01584                 goto out;
01585         }
01586         strupper_m(psp2);
01587         strlower_m(&psp2[strlen(spn)]);
01588         servicePrincipalName[1] = psp2;
01589 
01590         DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", 
01591                 psp2, machine_name));
01592 
01593         if ( (mods = ads_init_mods(ctx)) == NULL ) {
01594                 ret = ADS_ERROR(LDAP_NO_MEMORY);
01595                 goto out;
01596         }
01597         
01598         ret = ads_add_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName);
01599         if (!ADS_ERR_OK(ret)) {
01600                 DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n"));
01601                 goto out;
01602         }
01603         
01604         if ( (dn_string = ads_get_dn(ads, res)) == NULL ) {
01605                 ret = ADS_ERROR(LDAP_NO_MEMORY);
01606                 goto out;
01607         }
01608         
01609         ret = ads_gen_mod(ads, dn_string, mods);
01610         ads_memfree(ads,dn_string);
01611         if (!ADS_ERR_OK(ret)) {
01612                 DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n"));
01613                 goto out;
01614         }
01615 
01616  out:
01617         TALLOC_FREE( ctx );
01618         ads_msgfree(ads, res);
01619         return ret;
01620 }

ADS_STATUS ads_create_machine_acct ( ADS_STRUCT ads,
const char *  machine_name,
const char *  org_unit 
)

adds a machine account to the ADS server

引数:
ads An intialized ADS_STRUCT
machine_name - the NetBIOS machine name of this account.
account_type A number indicating the type of account to create
org_unit The LDAP path in which to place this account
戻り値:
0 upon success, or non-zero otherwise

ldap.c1631 行で定義されています。

参照先 ads_gen_add()ads_init_mods()ads_mod_str()ads_mod_strlist()ads_msgfree()ctxescape_rdn_val_string_alloc()talloc_asprintf()talloc_init().

参照元 net_precreate_machine_acct().

01633 {
01634         ADS_STATUS ret;
01635         char *samAccountName, *controlstr;
01636         TALLOC_CTX *ctx;
01637         ADS_MODLIST mods;
01638         char *machine_escaped = NULL;
01639         char *new_dn;
01640         const char *objectClass[] = {"top", "person", "organizationalPerson",
01641                                      "user", "computer", NULL};
01642         LDAPMessage *res = NULL;
01643         uint32 acct_control = ( UF_WORKSTATION_TRUST_ACCOUNT |\
01644                                 UF_DONT_EXPIRE_PASSWD |\
01645                                 UF_ACCOUNTDISABLE );
01646                               
01647         if (!(ctx = talloc_init("ads_add_machine_acct")))
01648                 return ADS_ERROR(LDAP_NO_MEMORY);
01649 
01650         ret = ADS_ERROR(LDAP_NO_MEMORY);
01651 
01652         machine_escaped = escape_rdn_val_string_alloc(machine_name);
01653         if (!machine_escaped) {
01654                 goto done;
01655         }
01656 
01657         new_dn = talloc_asprintf(ctx, "cn=%s,%s", machine_escaped, org_unit);
01658         samAccountName = talloc_asprintf(ctx, "%s$", machine_name);
01659 
01660         if ( !new_dn || !samAccountName ) {
01661                 goto done;
01662         }
01663         
01664 #ifndef ENCTYPE_ARCFOUR_HMAC
01665         acct_control |= UF_USE_DES_KEY_ONLY;
01666 #endif
01667 
01668         if (!(controlstr = talloc_asprintf(ctx, "%u", acct_control))) {
01669                 goto done;
01670         }
01671 
01672         if (!(mods = ads_init_mods(ctx))) {
01673                 goto done;
01674         }
01675         
01676         ads_mod_str(ctx, &mods, "cn", machine_name);
01677         ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName);
01678         ads_mod_strlist(ctx, &mods, "objectClass", objectClass);
01679         ads_mod_str(ctx, &mods, "userAccountControl", controlstr);
01680 
01681         ret = ads_gen_add(ads, new_dn, mods);
01682 
01683 done:
01684         SAFE_FREE(machine_escaped);
01685         ads_msgfree(ads, res);
01686         talloc_destroy(ctx);
01687         
01688         return ret;
01689 }

static void dump_binary ( const char *  field,
struct berval **  values 
) [static]

ldap.c1694 行で定義されています。

参照先 printf().

参照元 ads_dump_field().

01695 {
01696         int i, j;
01697         for (i=0; values[i]; i++) {
01698                 printf("%s: ", field);
01699                 for (j=0; j<values[i]->bv_len; j++) {
01700                         printf("%02X", (unsigned char)values[i]->bv_val[j]);
01701                 }
01702                 printf("\n");
01703         }
01704 }

static void dump_guid ( const char *  field,
struct berval **  values 
) [static]

ldap.c1706 行で定義されています。

参照先 uuid_flat::infoprintf()smb_uuid_string_static()smb_uuid_unpack_static().

参照元 ads_dump_field().

01707 {
01708         int i;
01709         UUID_FLAT guid;
01710         for (i=0; values[i]; i++) {
01711                 memcpy(guid.info, values[i]->bv_val, sizeof(guid.info));
01712                 printf("%s: %s\n", field, 
01713                        smb_uuid_string_static(smb_uuid_unpack_static(guid)));
01714         }
01715 }

static void dump_sid ( const char *  field,
struct berval **  values 
) [static]

ldap.c1720 行で定義されています。

参照先 printf()sid_parse()sid_string_static().

参照元 ads_dump_field().

01721 {
01722         int i;
01723         for (i=0; values[i]; i++) {
01724                 DOM_SID sid;
01725                 sid_parse(values[i]->bv_val, values[i]->bv_len, &sid);
01726                 printf("%s: %s\n", field, sid_string_static(&sid));
01727         }
01728 }

static void dump_sd ( const char *  filed,
struct berval **  values 
) [static]

ldap.c1733 行で定義されています。

参照先 ads_disp_sd()ctxprs_init()prs_mem_free()sec_io_desc()talloc_init().

参照元 ads_dump_field().

01734 {
01735         prs_struct ps;
01736         
01737         SEC_DESC   *psd = 0;
01738         TALLOC_CTX *ctx = 0;
01739 
01740         if (!(ctx = talloc_init("sec_io_desc")))
01741                 return;
01742 
01743         /* prepare data */
01744         prs_init(&ps, values[0]->bv_len, ctx, UNMARSHALL);
01745         prs_copy_data_in(&ps, values[0]->bv_val, values[0]->bv_len);
01746         prs_set_offset(&ps,0);
01747 
01748         /* parse secdesc */
01749         if (!sec_io_desc("sd", &psd, &ps, 1)) {
01750                 prs_mem_free(&ps);
01751                 talloc_destroy(ctx);
01752                 return;
01753         }
01754         if (psd) ads_disp_sd(psd);
01755 
01756         prs_mem_free(&ps);
01757         talloc_destroy(ctx);
01758 }

static void dump_string ( const char *  field,
char **  values 
) [static]

ldap.c1763 行で定義されています。

参照先 printf().

参照元 ads_dump_field().

01764 {
01765         int i;
01766         for (i=0; values[i]; i++) {
01767                 printf("%s: %s\n", field, values[i]);
01768         }
01769 }

static BOOL ads_dump_field ( char *  field,
void **  values,
void *  data_area 
) [static]

ldap.c1776 行で定義されています。

参照先 dump_binary()dump_guid()dump_sd()dump_sid()dump_string()nameprintf()StrCaseCmp()string.

参照元 ads_dump().

01777 {
01778         const struct {
01779                 const char *name;
01780                 BOOL string;
01781                 void (*handler)(const char *, struct berval **);
01782         } handlers[] = {
01783                 {"objectGUID", False, dump_guid},
01784                 {"netbootGUID", False, dump_guid},
01785                 {"nTSecurityDescriptor", False, dump_sd},
01786                 {"dnsRecord", False, dump_binary},
01787                 {"objectSid", False, dump_sid},
01788                 {"tokenGroups", False, dump_sid},
01789                 {"tokenGroupsNoGCAcceptable", False, dump_sid},
01790                 {"tokengroupsGlobalandUniversal", False, dump_sid},
01791                 {"mS-DS-CreatorSID", False, dump_sid},
01792                 {NULL, True, NULL}
01793         };
01794         int i;
01795 
01796         if (!field) { /* must be end of an entry */
01797                 printf("\n");
01798                 return False;
01799         }
01800 
01801         for (i=0; handlers[i].name; i++) {
01802                 if (StrCaseCmp(handlers[i].name, field) == 0) {
01803                         if (!values) /* first time, indicate string or not */
01804                                 return handlers[i].string;
01805                         handlers[i].handler(field, (struct berval **) values);
01806                         break;
01807                 }
01808         }
01809         if (!handlers[i].name) {
01810                 if (!values) /* first time, indicate string conversion */
01811                         return True;
01812                 dump_string(field, (char **)values);
01813         }
01814         return False;
01815 }

void ads_dump ( ADS_STRUCT ads,
LDAPMessage *  res 
)

Dump a result from LDAP on stdout used for debugging

引数:
ads connection to ads server
res Results to dump

ldap.c1824 行で定義されています。

参照先 ads_dump_field()ads_process_results().

参照元 net_ads_dn()net_ads_printer_info()net_ads_printer_search()net_ads_search()net_ads_sid()net_ads_status().

01825 {
01826         ads_process_results(ads, res, ads_dump_field, NULL);
01827 }

void ads_process_results ( ADS_STRUCT ads,
LDAPMessage *  res,
BOOL(*)(char *, void **, void *)  fn,
void *  data_area 
)

Walk through results, calling a function for each entry found.

The function receives a field name, a berval * array of values, and a data area passed through from the start. The function is called once with null for field and values at the end of each entry.

引数:
ads connection to ads server
res Results to process
fn Function for processing each result
data_area user-defined area to pass to function

ldap.c1840 行で定義されています。

参照先 ads_first_entry()ads_next_entry()ads_pull_strvals()ctxfnADS_STRUCT::ldpull_utf8_talloc()stringtalloc_free_children()talloc_init().

参照元 ads_do_search_all_fn()ads_dump().

01843 {
01844         LDAPMessage *msg;
01845         TALLOC_CTX *ctx;
01846 
01847         if (!(ctx = talloc_init("ads_process_results")))
01848                 return;
01849 
01850         for (msg = ads_first_entry(ads, res); msg; 
01851              msg = ads_next_entry(ads, msg)) {
01852                 char *utf8_field;
01853                 BerElement *b;
01854         
01855                 for (utf8_field=ldap_first_attribute(ads->ld,
01856                                                      (LDAPMessage *)msg,&b); 
01857                      utf8_field;
01858                      utf8_field=ldap_next_attribute(ads->ld,
01859                                                     (LDAPMessage *)msg,b)) {
01860                         struct berval **ber_vals;
01861                         char **str_vals, **utf8_vals;
01862                         char *field;
01863                         BOOL string; 
01864 
01865                         pull_utf8_talloc(ctx, &field, utf8_field);
01866                         string = fn(field, NULL, data_area);
01867 
01868                         if (string) {
01869                                 utf8_vals = ldap_get_values(ads->ld,
01870                                                  (LDAPMessage *)msg, field);
01871                                 str_vals = ads_pull_strvals(ctx, 
01872                                                   (const char **) utf8_vals);
01873                                 fn(field, (void **) str_vals, data_area);
01874                                 ldap_value_free(utf8_vals);
01875                         } else {
01876                                 ber_vals = ldap_get_values_len(ads->ld, 
01877                                                  (LDAPMessage *)msg, field);
01878                                 fn(field, (void **) ber_vals, data_area);
01879 
01880                                 ldap_value_free_len(ber_vals);
01881                         }
01882                         ldap_memfree(utf8_field);
01883                 }
01884                 ber_free(b, 0);
01885                 talloc_free_children(ctx);
01886                 fn(NULL, NULL, data_area); /* completed an entry */
01887 
01888         }
01889         talloc_destroy(ctx);
01890 }

int ads_count_replies ( ADS_STRUCT ads,
void *  res 
)

count how many replies are in a LDAPMessage

引数:
ads connection to ads server
res Results to count
戻り値:
number of replies

ldap.c1898 行で定義されています。

参照先 ADS_STRUCT::ld.

参照元 ads_add_gpo_link()ads_add_service_principal_name()ads_clear_service_principal_names()ads_default_ou_string()ads_delete_gpo_link()ads_do_search_retry_internal()ads_find_printer_on_server()ads_get_attrname_by_oid()ads_get_attrnames_by_oids()ads_get_dnshostname()ads_get_gpo()ads_get_gpo_link()ads_get_kvno()ads_get_samaccountname()ads_get_upn()ads_group_add()ads_group_delete()ads_leave_realm()ads_site_dn_for_machine()ads_upn_suffixes()ads_user_add()ads_user_delete()ads_USN()enum_dom_groups()gpo_password_policy()idmap_ad_sids_to_unixids()lookup_groupmem()lookup_usergroups()lookup_usergroups_member()lookup_usergroups_memberof()net_ads_dn()net_ads_gpo_apply()net_ads_gpo_list()net_ads_gpo_refresh()net_ads_printer_info()net_ads_printer_publish()net_ads_printer_remove()net_ads_printer_search()net_ads_search()net_ads_sid()net_ads_status()net_derive_salting_principal()net_set_machine_spn()net_set_machine_upn()net_set_os_attributes()nt_printer_unpublish_ads()query_user()query_user_list().

01899 {
01900         return ldap_count_entries(ads->ld, (LDAPMessage *)res);
01901 }

LDAPMessage* ads_first_entry ( ADS_STRUCT ads,
LDAPMessage *  res 
)

pull the first entry from a ADS result

引数:
ads connection to ads server
res Results of search
戻り値:
first entry from result

ldap.c1909 行で定義されています。

参照先 ADS_STRUCT::ld.

参照元 ads_get_attrnames_by_oids()ads_leave_realm()ads_process_results()enum_dom_groups()idmap_ad_sids_to_unixids()lookup_usergroups_member()net_ads_gpo_list()query_user_list().

01910 {
01911         return ldap_first_entry(ads->ld, res);
01912 }

LDAPMessage* ads_next_entry ( ADS_STRUCT ads,
LDAPMessage *  res 
)

pull the next entry from a ADS result

引数:
ads connection to ads server
res Results of search
戻り値:
next entry from result

ldap.c1920 行で定義されています。

参照先 ADS_STRUCT::ld.

参照元 ads_get_attrnames_by_oids()ads_leave_realm()ads_process_results()enum_dom_groups()idmap_ad_sids_to_unixids()lookup_usergroups_member()net_ads_gpo_list()query_user_list().

01921 {
01922         return ldap_next_entry(ads->ld, res);
01923 }

LDAPMessage* ads_first_message ( ADS_STRUCT ads,
LDAPMessage *  res 
)

pull the first message from a ADS result

引数:
ads connection to ads server
res Results of search
戻り値:
first message from result

ldap.c1931 行で定義されています。

参照先 ADS_STRUCT::ld.

参照元 ads_do_search_all_args().

01932 {
01933         return ldap_first_message(ads->ld, res);
01934 }

LDAPMessage* ads_next_message ( ADS_STRUCT ads,
LDAPMessage *  res 
)

pull the next message from a ADS result

引数:
ads connection to ads server
res Results of search
戻り値:
next message from result

ldap.c1942 行で定義されています。

参照先 ADS_STRUCT::ld.

参照元 ads_do_search_all_args().

01943 {
01944         return ldap_next_message(ads->ld, res);
01945 }

char* ads_pull_string ( ADS_STRUCT ads,
TALLOC_CTX mem_ctx,
LDAPMessage *  msg,
const char *  field 
)

pull a single string from a ADS result

引数:
ads connection to ads server
mem_ctx TALLOC_CTX to use for allocating result string
msg Results of search
field Attribute to retrieve
戻り値:
Result string in talloc context

ldap.c1955 行で定義されています。

参照先 ADS_STRUCT::ldpull_utf8_talloc()values.

参照元 ads_add_gpo_link()ads_current_time()ads_delete_gpo_link()ads_get_attrname_by_oid()ads_get_attrnames_by_oids()ads_get_dnshostname()ads_get_gpo_link()ads_get_samaccountname()ads_get_upn()ads_parse_gpo()ads_pull_username()ads_schema_path()ads_site_dn()ads_site_dn_for_machine()ads_upn_suffixes()enum_dom_groups()net_derive_salting_principal()net_update_dns_internal()nss_ad_get_info()query_user()query_user_list().

01957 {
01958         char **values;
01959         char *ret = NULL;
01960         char *ux_string;
01961         size_t rc;
01962 
01963         values = ldap_get_values(ads->ld, msg, field);
01964         if (!values)
01965                 return NULL;
01966         
01967         if (values[0]) {
01968                 rc = pull_utf8_talloc(mem_ctx, &ux_string, 
01969                                       values[0]);
01970                 if (rc != (size_t)-1)
01971                         ret = ux_string;
01972                 
01973         }
01974         ldap_value_free(values);
01975         return ret;
01976 }

char** ads_pull_strings ( ADS_STRUCT ads,
TALLOC_CTX mem_ctx,
LDAPMessage *  msg,
const char *  field,
size_t *  num_values 
)

pull an array of strings from a ADS result

引数:
ads connection to ads server
mem_ctx TALLOC_CTX to use for allocating result string
msg Results of search
field Attribute to retrieve
戻り値:
Result strings in talloc context

ldap.c1986 行で定義されています。

参照先 ADS_STRUCT::ldpull_utf8_talloc()values.

参照元 ads_pull_sids_from_extendeddn()ads_pull_strings_range()ads_upn_suffixes().

01989 {
01990         char **values;
01991         char **ret = NULL;
01992         int i;
01993 
01994         values = ldap_get_values(ads->ld, msg, field);
01995         if (!values)
01996                 return NULL;
01997 
01998         *num_values = ldap_count_values(values);
01999 
02000         ret = TALLOC_ARRAY(mem_ctx, char *, *num_values + 1);
02001         if (!ret) {
02002                 ldap_value_free(values);
02003                 return NULL;
02004         }
02005 
02006         for (i=0;i<*num_values;i++) {
02007                 if (pull_utf8_talloc(mem_ctx, &ret[i], values[i]) == -1) {
02008                         ldap_value_free(values);
02009                         return NULL;
02010                 }
02011         }
02012         ret[i] = NULL;
02013 
02014         ldap_value_free(values);
02015         return ret;
02016 }

char** ads_pull_strings_range ( ADS_STRUCT ads,
TALLOC_CTX mem_ctx,
LDAPMessage *  msg,
const char *  field,
char **  current_strings,
const char **  next_attribute,
size_t *  num_strings,
BOOL more_strings 
)

pull an array of strings from a ADS result (handle large multivalue attributes with range retrieval)

引数:
ads connection to ads server
mem_ctx TALLOC_CTX to use for allocating result string
msg Results of search
field Attribute to retrieve
current_strings strings returned by a previous call to this function
next_attribute The next query should ask for this attribute
num_values How many values did we get this time?
more_values Are there more values to get?
戻り値:
Result strings in talloc context

ldap.c2031 行で定義されています。

参照先 ads_pull_strings()ADS_STRUCT::ldstrnequal()talloc_asprintf().

参照元 lookup_groupmem().

02038 {
02039         char *attr;
02040         char *expected_range_attrib, *range_attr;
02041         BerElement *ptr = NULL;
02042         char **strings;
02043         char **new_strings;
02044         size_t num_new_strings;
02045         unsigned long int range_start;
02046         unsigned long int range_end;
02047         
02048         /* we might have been given the whole lot anyway */
02049         if ((strings = ads_pull_strings(ads, mem_ctx, msg, field, num_strings))) {
02050                 *more_strings = False;
02051                 return strings;
02052         }
02053 
02054         expected_range_attrib = talloc_asprintf(mem_ctx, "%s;Range=", field);
02055 
02056         /* look for Range result */
02057         for (attr = ldap_first_attribute(ads->ld, (LDAPMessage *)msg, &ptr); 
02058              attr; 
02059              attr = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, ptr)) {
02060                 /* we ignore the fact that this is utf8, as all attributes are ascii... */
02061                 if (strnequal(attr, expected_range_attrib, strlen(expected_range_attrib))) {
02062                         range_attr = attr;
02063                         break;
02064                 }
02065                 ldap_memfree(attr);
02066         }
02067         if (!attr) {
02068                 ber_free(ptr, 0);
02069                 /* nothing here - this field is just empty */
02070                 *more_strings = False;
02071                 return NULL;
02072         }
02073         
02074         if (sscanf(&range_attr[strlen(expected_range_attrib)], "%lu-%lu", 
02075                    &range_start, &range_end) == 2) {
02076                 *more_strings = True;
02077         } else {
02078                 if (sscanf(&range_attr[strlen(expected_range_attrib)], "%lu-*", 
02079                            &range_start) == 1) {
02080                         *more_strings = False;
02081                 } else {
02082                         DEBUG(1, ("ads_pull_strings_range:  Cannot parse Range attriubte (%s)\n", 
02083                                   range_attr));
02084                         ldap_memfree(range_attr);
02085                         *more_strings = False;
02086                         return NULL;
02087                 }
02088         }
02089 
02090         if ((*num_strings) != range_start) {
02091                 DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) doesn't start at %u, but at %lu"
02092                           " - aborting range retreival\n",
02093                           range_attr, (unsigned int)(*num_strings) + 1, range_start));
02094                 ldap_memfree(range_attr);
02095                 *more_strings = False;
02096                 return NULL;
02097         }
02098 
02099         new_strings = ads_pull_strings(ads, mem_ctx, msg, range_attr, &num_new_strings);
02100         
02101         if (*more_strings && ((*num_strings + num_new_strings) != (range_end + 1))) {
02102                 DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) tells us we have %lu "
02103                           "strings in this bunch, but we only got %lu - aborting range retreival\n",
02104                           range_attr, (unsigned long int)range_end - range_start + 1, 
02105                           (unsigned long int)num_new_strings));
02106                 ldap_memfree(range_attr);
02107                 *more_strings = False;
02108                 return NULL;
02109         }
02110 
02111         strings = TALLOC_REALLOC_ARRAY(mem_ctx, current_strings, char *,
02112                                  *num_strings + num_new_strings);
02113         
02114         if (strings == NULL) {
02115                 ldap_memfree(range_attr);
02116                 *more_strings = False;
02117                 return NULL;
02118         }
02119         
02120         if (new_strings && num_new_strings) {
02121                 memcpy(&strings[*num_strings], new_strings,
02122                        sizeof(*new_strings) * num_new_strings);
02123         }
02124 
02125         (*num_strings) += num_new_strings;
02126 
02127         if (*more_strings) {
02128                 *next_attribute = talloc_asprintf(mem_ctx,
02129                                                   "%s;range=%d-*", 
02130                                                   field,
02131                                                   (int)*num_strings);
02132                 
02133                 if (!*next_attribute) {
02134                         DEBUG(1, ("talloc_asprintf for next attribute failed!\n"));
02135                         ldap_memfree(range_attr);
02136                         *more_strings = False;
02137                         return NULL;
02138                 }
02139         }
02140 
02141         ldap_memfree(range_attr);
02142 
02143         return strings;
02144 }

BOOL ads_pull_uint32 ( ADS_STRUCT ads,
LDAPMessage *  msg,
const char *  field,
uint32 *  v 
)

pull a single uint32 from a ADS result

引数:
ads connection to ads server
msg Results of search
field Attribute to retrieve
v Pointer to int to store result
戻り値:
boolean inidicating success

ldap.c2154 行で定義されています。

参照先 ADS_STRUCT::ldvalues.

参照元 ads_domain_func_level()ads_get_gpo_link()ads_get_kvno()ads_parse_gpo()ads_USN()dn_lookup()gpo_password_policy()idmap_ad_sids_to_unixids()lookup_groupmem()lookup_usergroups()net_ads_gpo_apply()net_ads_gpo_refresh()nss_ad_get_info()query_user()query_user_list().

02156 {
02157         char **values;
02158 
02159         values = ldap_get_values(ads->ld, msg, field);
02160         if (!values)
02161                 return False;
02162         if (!values[0]) {
02163                 ldap_value_free(values);
02164                 return False;
02165         }
02166 
02167         *v = atoi(values[0]);
02168         ldap_value_free(values);
02169         return True;
02170 }

BOOL ads_pull_guid ( ADS_STRUCT ads,
LDAPMessage *  msg,
struct GUID guid 
)

pull a single objectGUID from an ADS result

引数:
ads connection to ADS server
msg results of search
guid 37-byte area to receive text guid
戻り値:
boolean indicating success

ldap.c2179 行で定義されています。

参照先 uuid_flat::infoADS_STRUCT::ldsmb_uuid_unpack()values.

参照元 nt_printer_publish_ads().

02180 {
02181         char **values;
02182         UUID_FLAT flat_guid;
02183 
02184         values = ldap_get_values(ads->ld, msg, "objectGUID");
02185         if (!values)
02186                 return False;
02187         
02188         if (values[0]) {
02189                 memcpy(&flat_guid.info, values[0], sizeof(UUID_FLAT));
02190                 smb_uuid_unpack(flat_guid, guid);
02191                 ldap_value_free(values);
02192                 return True;
02193         }
02194         ldap_value_free(values);
02195         return False;
02196 
02197 }

BOOL ads_pull_sid ( ADS_STRUCT ads,
LDAPMessage *  msg,
const char *  field,
DOM_SID sid 
)

pull a single DOM_SID from a ADS result

引数:
ads connection to ads server
msg Results of search
field Attribute to retrieve
sid Pointer to sid to store result
戻り値:
boolean inidicating success

ldap.c2208 行で定義されています。

参照先 ADS_STRUCT::ldsid_parse()values.

参照元 ads_domain_sid()dn_lookup()enum_dom_groups()idmap_ad_sids_to_unixids()lookup_usergroups_member()query_user_list().

02210 {
02211         struct berval **values;
02212         BOOL ret = False;
02213 
02214         values = ldap_get_values_len(ads->ld, msg, field);
02215 
02216         if (!values)
02217                 return False;
02218 
02219         if (values[0])
02220                 ret = sid_parse(values[0]->bv_val, values[0]->bv_len, sid);
02221         
02222         ldap_value_free_len(values);
02223         return ret;
02224 }

int ads_pull_sids ( ADS_STRUCT ads,
TALLOC_CTX mem_ctx,
LDAPMessage *  msg,
const char *  field,
DOM_SID **  sids 
)

pull an array of DOM_SIDs from a ADS result

引数:
ads connection to ads server
mem_ctx TALLOC_CTX for allocating sid array
msg Results of search
field Attribute to retrieve
sids pointer to sid array to allocate
戻り値:
the count of SIDs pulled

ldap.c2235 行で定義されています。

参照先 ADS_STRUCT::ldsid_parse()sid_to_string()values.

参照元 lookup_usergroups().

02237 {
02238         struct berval **values;
02239         BOOL ret;
02240         int count, i;
02241 
02242         values = ldap_get_values_len(ads->ld, msg, field);
02243 
02244         if (!values)
02245                 return 0;
02246 
02247         for (i=0; values[i]; i++)
02248                 /* nop */ ;
02249 
02250         if (i) {
02251                 (*sids) = TALLOC_ARRAY(mem_ctx, DOM_SID, i);
02252                 if (!(*sids)) {
02253                         ldap_value_free_len(values);
02254                         return 0;
02255                 }
02256         } else {
02257                 (*sids) = NULL;
02258         }
02259 
02260         count = 0;
02261         for (i=0; values[i]; i++) {
02262                 ret = sid_parse(values[i]->bv_val, values[i]->bv_len, &(*sids)[count]);
02263                 if (ret) {
02264                         fstring sid;
02265                         DEBUG(10, ("pulling SID: %s\n", sid_to_string(sid, &(*sids)[count])));
02266                         count++;
02267                 }
02268         }
02269         
02270         ldap_value_free_len(values);
02271         return count;
02272 }

BOOL ads_pull_sd ( ADS_STRUCT ads,
TALLOC_CTX mem_ctx,
LDAPMessage *  msg,
const char *  field,
SEC_DESC **  sd 
)

pull a SEC_DESC from a ADS result

引数:
ads connection to ads server
mem_ctx TALLOC_CTX for allocating sid array
msg Results of search
field Attribute to retrieve
sd Pointer to *SEC_DESC to store result (talloc()ed)
戻り値:
boolean inidicating success

ldap.c2283 行で定義されています。

参照先 ADS_STRUCT::ldprs_init()prs_mem_free()sec_io_desc()values.

02285 {
02286         struct berval **values;
02287         BOOL ret = False;
02288 
02289         values = ldap_get_values_len(ads->ld, msg, field);
02290 
02291         if (!values) return False;
02292 
02293         if (values[0]) {
02294                 prs_struct ps;
02295                 prs_init(&ps, values[0]->bv_len, mem_ctx, UNMARSHALL);
02296                 prs_copy_data_in(&ps, values[0]->bv_val, values[0]->bv_len);
02297                 prs_set_offset(&ps,0);
02298 
02299                 ret = sec_io_desc("sd", sd, &ps, 1);
02300                 prs_mem_free(&ps);
02301         }
02302         
02303         ldap_value_free_len(values);
02304         return ret;
02305 }

char* ads_pull_username ( ADS_STRUCT ads,
TALLOC_CTX mem_ctx,
LDAPMessage *  msg 
)

ldap.c2317 行で定義されています。

参照先 ads_pull_string()strchr_m().

参照元 dn_lookup()enum_dom_groups()query_user()query_user_list().

02319 {
02320 #if 0   /* JERRY */
02321         char *ret, *p;
02322 
02323         /* lookup_name() only works on the sAMAccountName to 
02324            returning the username portion of userPrincipalName
02325            breaks winbindd_getpwnam() */
02326 
02327         ret = ads_pull_string(ads, mem_ctx, msg, "userPrincipalName");
02328         if (ret && (p = strchr_m(ret, '@'))) {
02329                 *p = 0;
02330                 return ret;
02331         }
02332 #endif
02333         return ads_pull_string(ads, mem_ctx, msg, "sAMAccountName");
02334 }

ADS_STATUS ads_USN ( ADS_STRUCT ads,
uint32 *  usn 
)

find the update serial number - this is the core of the ldap cache

引数:
ads connection to ads server
ads connection to ADS server
usn Pointer to retrieved update serial number
戻り値:
status of search

ldap.c2344 行で定義されています。

参照先 ads_count_replies()ads_do_search_retry()ads_msgfree()ads_pull_uint32()status.

参照元 sequence_number().

02345 {
02346         const char *attrs[] = {"highestCommittedUSN", NULL};
02347         ADS_STATUS status;
02348         LDAPMessage *res;
02349 
02350         status = ads_do_search_retry(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
02351         if (!ADS_ERR_OK(status)) 
02352                 return status;
02353 
02354         if (ads_count_replies(ads, res) != 1) {
02355                 ads_msgfree(ads, res);
02356                 return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
02357         }
02358 
02359         if (!ads_pull_uint32(ads, res, "highestCommittedUSN", usn)) {
02360                 ads_msgfree(ads, res);
02361                 return ADS_ERROR(LDAP_NO_SUCH_ATTRIBUTE);
02362         }
02363 
02364         ads_msgfree(ads, res);
02365         return ADS_SUCCESS;
02366 }

static time_t ads_parse_time ( const char *  str  )  [static]

ldap.c2371 行で定義されています。

参照元 ads_current_time().

02372 {
02373         struct tm tm;
02374 
02375         ZERO_STRUCT(tm);
02376 
02377         if (sscanf(str, "%4d%2d%2d%2d%2d%2d", 
02378                    &tm.tm_year, &tm.tm_mon, &tm.tm_mday, 
02379                    &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
02380                 return 0;
02381         }
02382         tm.tm_year -= 1900;
02383         tm.tm_mon -= 1;
02384 
02385         return timegm(&tm);
02386 }

ADS_STATUS ads_current_time ( ADS_STRUCT ads  ) 

ldap.c2391 行で定義されています。

参照先 ads_connect()ads_destroy()ads_do_search()ads_init()ads_msgfree()ads_parse_time()ads_pull_string()ADS_STRUCT::authADS_STRUCT::configctxADS_STRUCT::current_timeADS_STRUCT::flagsADS_STRUCT::ldADS_STRUCT::ldap_serverADS_STRUCT::realmADS_STRUCT::serverstatustalloc_init()ADS_STRUCT::time_offsetADS_STRUCT::workgroup.

参照元 ads_connect()net_ads_info().

02392 {
02393         const char *attrs[] = {"currentTime", NULL};
02394         ADS_STATUS status;
02395         LDAPMessage *res;
02396         char *timestr;
02397         TALLOC_CTX *ctx;
02398         ADS_STRUCT *ads_s = ads;
02399 
02400         if (!(ctx = talloc_init("ads_current_time"))) {
02401                 return ADS_ERROR(LDAP_NO_MEMORY);
02402         }
02403 
02404         /* establish a new ldap tcp session if necessary */
02405 
02406         if ( !ads->ld ) {
02407                 if ( (ads_s = ads_init( ads->server.realm, ads->server.workgroup, 
02408                         ads->server.ldap_server )) == NULL )
02409                 {
02410                         goto done;
02411                 }
02412                 ads_s->auth.flags = ADS_AUTH_ANON_BIND;
02413                 status = ads_connect( ads_s );
02414                 if ( !ADS_ERR_OK(status))
02415                         goto done;
02416         }
02417 
02418         status = ads_do_search(ads_s, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
02419         if (!ADS_ERR_OK(status)) {
02420                 goto done;
02421         }
02422 
02423         timestr = ads_pull_string(ads_s, ctx, res, "currentTime");
02424         if (!timestr) {
02425                 ads_msgfree(ads_s, res);
02426                 status = ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
02427                 goto done;
02428         }
02429 
02430         /* but save the time and offset in the original ADS_STRUCT */   
02431         
02432         ads->config.current_time = ads_parse_time(timestr);
02433 
02434         if (ads->config.current_time != 0) {
02435                 ads->auth.time_offset = ads->config.current_time - time(NULL);
02436                 DEBUG(4,("time offset is %d seconds\n", ads->auth.time_offset));
02437         }
02438 
02439         ads_msgfree(ads, res);
02440 
02441         status = ADS_SUCCESS;
02442 
02443 done:
02444         /* free any temporary ads connections */
02445         if ( ads_s != ads ) {
02446                 ads_destroy( &ads_s );
02447         }
02448         talloc_destroy(ctx);
02449 
02450         return status;
02451 }

ADS_STATUS ads_domain_func_level ( ADS_STRUCT ads,
uint32 *  val 
)

ldap.c2456 行で定義されています。

参照先 ads_connect()ads_destroy()ads_do_search()ads_init()ads_msgfree()ads_pull_uint32()ADS_STRUCT::authADS_STRUCT::flagsADS_STRUCT::ldADS_STRUCT::ldap_serverADS_STRUCT::realmADS_STRUCT::serverstatusADS_STRUCT::workgroup.

参照元 net_derive_salting_principal().

02457 {
02458         const char *attrs[] = {"domainFunctionality", NULL};
02459         ADS_STATUS status;
02460         LDAPMessage *res;
02461         ADS_STRUCT *ads_s = ads;
02462         
02463         *val = DS_DOMAIN_FUNCTION_2000;
02464 
02465         /* establish a new ldap tcp session if necessary */
02466 
02467         if ( !ads->ld ) {
02468                 if ( (ads_s = ads_init( ads->server.realm, ads->server.workgroup, 
02469                         ads->server.ldap_server )) == NULL )
02470                 {
02471                         goto done;
02472                 }
02473                 ads_s->auth.flags = ADS_AUTH_ANON_BIND;
02474                 status = ads_connect( ads_s );
02475                 if ( !ADS_ERR_OK(status))
02476                         goto done;
02477         }
02478 
02479         /* If the attribute does not exist assume it is a Windows 2000 
02480            functional domain */
02481            
02482         status = ads_do_search(ads_s, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
02483         if (!ADS_ERR_OK(status)) {
02484                 if ( status.err.rc == LDAP_NO_SUCH_ATTRIBUTE ) {
02485                         status = ADS_SUCCESS;
02486                 }
02487                 goto done;
02488         }
02489 
02490         if ( !ads_pull_uint32(ads_s, res, "domainFunctionality", val) ) {
02491                 DEBUG(5,("ads_domain_func_level: Failed to pull the domainFunctionality attribute.\n"));
02492         }
02493         DEBUG(3,("ads_domain_func_level: %d\n", *val));
02494 
02495         
02496         ads_msgfree(ads, res);
02497 
02498 done:
02499         /* free any temporary ads connections */
02500         if ( ads_s != ads ) {
02501                 ads_destroy( &ads_s );
02502         }
02503 
02504         return status;
02505 }

ADS_STATUS ads_domain_sid ( ADS_STRUCT ads,
DOM_SID sid 
)

find the domain sid for our domain

引数:
ads connection to ads server
sid Pointer to domain sid
戻り値:
status of search

ldap.c2513 行で定義されています。

参照先 ads_do_search_retry()ads_msgfree()ads_pull_sid()ADS_STRUCT::bind_pathADS_STRUCT::config.

02514 {
02515         const char *attrs[] = {"objectSid", NULL};
02516         LDAPMessage *res;
02517         ADS_STATUS rc;
02518 
02519         rc = ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_BASE, "(objectclass=*)", 
02520                            attrs, &res);
02521         if (!ADS_ERR_OK(rc)) return rc;
02522         if (!ads_pull_sid(ads, res, "objectSid", sid)) {
02523                 ads_msgfree(ads, res);
02524                 return ADS_ERROR_SYSTEM(ENOENT);
02525         }
02526         ads_msgfree(ads, res);
02527         
02528         return ADS_SUCCESS;
02529 }

ADS_STATUS ads_site_dn ( ADS_STRUCT ads,
TALLOC_CTX mem_ctx,
const char **  site_name 
)

find our site name

引数:
ads connection to ads server
mem_ctx Pointer to talloc context
site_name Pointer to the sitename
戻り値:
status of search

ldap.c2538 行で定義されています。

参照先 ads_do_search()ads_msgfree()ads_parent_dn()ads_pull_string()statustalloc_strdup().

参照元 ads_site_dn_for_machine().

02539 {
02540         ADS_STATUS status;
02541         LDAPMessage *res;
02542         const char *dn, *service_name;
02543         const char *attrs[] = { "dsServiceName", NULL };
02544 
02545         status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
02546         if (!ADS_ERR_OK(status)) {
02547                 return status;
02548         }
02549 
02550         service_name = ads_pull_string(ads, mem_ctx, res, "dsServiceName");
02551         if (service_name == NULL) {
02552                 ads_msgfree(ads, res);
02553                 return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
02554         }
02555 
02556         ads_msgfree(ads, res);
02557 
02558         /* go up three levels */
02559         dn = ads_parent_dn(ads_parent_dn(ads_parent_dn(service_name)));
02560         if (dn == NULL) {
02561                 return ADS_ERROR(LDAP_NO_MEMORY);
02562         }
02563 
02564         *site_name = talloc_strdup(mem_ctx, dn);
02565         if (*site_name == NULL) {
02566                 return ADS_ERROR(LDAP_NO_MEMORY);
02567         }
02568 
02569         return status;
02570         /*
02571         dsServiceName: CN=NTDS Settings,CN=W2K3DC,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=ber,DC=suse,DC=de
02572         */                                               
02573 }

ADS_STATUS ads_site_dn_for_machine ( ADS_STRUCT ads,
TALLOC_CTX mem_ctx,
const char *  computer_name,
const char **  site_dn 
)

find the site dn where a machine resides

引数:
ads connection to ads server
mem_ctx Pointer to talloc context
computer_name name of the machine
site_name Pointer to the sitename
戻り値:
status of search

ldap.c2583 行で定義されています。

参照先 ads_count_replies()ads_do_search()ads_get_dn()ads_memfree()ads_msgfree()ads_parent_dn()ads_pull_string()ads_site_dn()ADS_STRUCT::configADS_STRUCT::ldap_server_namestatusstrequal()talloc_asprintf()talloc_strdup().

参照元 ads_get_gpo_list().

02584 {
02585         ADS_STATUS status;
02586         LDAPMessage *res;
02587         const char *parent, *config_context, *filter;
02588         const char *attrs[] = { "configurationNamingContext", NULL };
02589         char *dn;
02590 
02591         /* shortcut a query */
02592         if (strequal(computer_name, ads->config.ldap_server_name)) {
02593                 return ads_site_dn(ads, mem_ctx, site_dn);
02594         }
02595 
02596         status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
02597         if (!ADS_ERR_OK(status)) {
02598                 return status;
02599         }
02600 
02601         config_context = ads_pull_string(ads, mem_ctx, res, "configurationNamingContext");
02602         if (config_context == NULL) {
02603                 ads_msgfree(ads, res);
02604                 return ADS_ERROR(LDAP_NO_MEMORY);
02605         }
02606 
02607         filter = talloc_asprintf(mem_ctx, "(cn=%s)", computer_name);
02608         if (filter == NULL) {
02609                 ads_msgfree(ads, res);
02610                 return ADS_ERROR(LDAP_NO_MEMORY);
02611         }
02612 
02613         ads_msgfree(ads, res);
02614 
02615         status = ads_do_search(ads, config_context, LDAP_SCOPE_SUBTREE, filter, NULL, &res);
02616         if (!ADS_ERR_OK(status)) {
02617                 return status;
02618         }
02619 
02620         if (ads_count_replies(ads, res) != 1) {
02621                 ads_msgfree(ads, res);
02622                 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
02623         }
02624 
02625         dn = ads_get_dn(ads, res);
02626         if (dn == NULL) {
02627                 ads_msgfree(ads, res);
02628                 return ADS_ERROR(LDAP_NO_MEMORY);
02629         }
02630 
02631         /* go up three levels */
02632         parent = ads_parent_dn(ads_parent_dn(ads_parent_dn(dn)));
02633         if (parent == NULL) {
02634                 ads_msgfree(ads, res);
02635                 ads_memfree(ads, dn);
02636                 return ADS_ERROR(LDAP_NO_MEMORY);
02637         }
02638 
02639         *site_dn = talloc_strdup(mem_ctx, parent);
02640         if (*site_dn == NULL) {
02641                 ads_msgfree(ads, res);
02642                 ads_memfree(ads, dn);
02643                 return ADS_ERROR(LDAP_NO_MEMORY);
02644         }
02645 
02646         ads_memfree(ads, dn);
02647         ads_msgfree(ads, res);
02648 
02649         return status;
02650 }

ADS_STATUS ads_upn_suffixes ( ADS_STRUCT ads,
TALLOC_CTX mem_ctx,
char ***  suffixes,
size_t *  num_suffixes 
)

get the upn suffixes for a domain

引数:
ads connection to ads server
mem_ctx Pointer to talloc context
suffixes Pointer to an array of suffixes
num_suffixes Pointer to the number of suffixes
戻り値:
status of search

ldap.c2660 行で定義されています。

参照先 ads_count_replies()ads_do_search()ads_msgfree()ads_pull_string()ads_pull_strings()ads_search_dn()statustalloc_asprintf().

02661 {
02662         ADS_STATUS status;
02663         LDAPMessage *res;
02664         const char *config_context, *base;
02665         const char *attrs[] = { "configurationNamingContext", NULL };
02666         const char *attrs2[] = { "uPNSuffixes", NULL };
02667 
02668         status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
02669         if (!ADS_ERR_OK(status)) {
02670                 return status;
02671         }
02672 
02673         config_context = ads_pull_string(ads, mem_ctx, res, "configurationNamingContext");
02674         if (config_context == NULL) {
02675                 ads_msgfree(ads, res);
02676                 return ADS_ERROR(LDAP_NO_MEMORY);
02677         }
02678 
02679         ads_msgfree(ads, res);
02680 
02681         base = talloc_asprintf(mem_ctx, "cn=Partitions,%s", config_context);
02682         if (base == NULL) {
02683                 return ADS_ERROR(LDAP_NO_MEMORY);
02684         }
02685 
02686         status = ads_search_dn(ads, &res, base, attrs2); 
02687         if (!ADS_ERR_OK(status)) {
02688                 return status;
02689         }
02690 
02691         if (ads_count_replies(ads, res) != 1) {
02692                 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
02693         }
02694 
02695         (*suffixes) = ads_pull_strings(ads, mem_ctx, res, "uPNSuffixes", num_suffixes);
02696         if ((*suffixes) == NULL) {
02697                 ads_msgfree(ads, res);
02698                 return ADS_ERROR(LDAP_NO_MEMORY);
02699         }
02700 
02701         ads_msgfree(ads, res);
02702 
02703         return status;
02704 }

BOOL ads_get_sid_from_extended_dn ( TALLOC_CTX mem_ctx,
const char *  dn,
enum ads_extended_dn_flags  flags,
DOM_SID sid 
)

pull a DOM_SID from an extended dn string

引数:
mem_ctx TALLOC_CTX
flags string type of extended_dn
sid pointer to a DOM_SID
戻り値:
boolean inidicating success

ldap.c2713 行で定義されています。

参照先 ADS_EXTENDED_DN_HEX_STRINGADS_EXTENDED_DN_STRINGbufsid_parse()strhex_to_str()string_to_sid().

参照元 ads_pull_sids_from_extendeddn().

02717 {
02718         char *p, *q;
02719 
02720         if (!dn) {
02721                 return False;
02722         }
02723 
02724         /* 
02725          * ADS_EXTENDED_DN_HEX_STRING:
02726          * <GUID=238e1963cb390f4bb032ba0105525a29>;<SID=010500000000000515000000bb68c8fd6b61b427572eb04556040000>;CN=gd,OU=berlin,OU=suse,DC=ber,DC=suse,DC=de
02727          *
02728          * ADS_EXTENDED_DN_STRING (only with w2k3):
02729         <GUID=63198e23-39cb-4b0f-b032-ba0105525a29>;<SID=S-1-5-21-4257769659-666132843-1169174103-1110>;CN=gd,OU=berlin,OU=suse,DC=ber,DC=suse,DC=de
02730          */
02731 
02732         p = strchr(dn, ';');
02733         if (!p) {
02734                 return False;
02735         }
02736 
02737         if (strncmp(p, ";<SID=", strlen(";<SID=")) != 0) {
02738                 return False;
02739         }
02740 
02741         p += strlen(";<SID=");
02742 
02743         q = strchr(p, '>');
02744         if (!q) {
02745                 return False;
02746         }
02747         
02748         *q = '\0';
02749 
02750         DEBUG(100,("ads_get_sid_from_extended_dn: sid string is %s\n", p));
02751 
02752         switch (flags) {
02753         
02754         case ADS_EXTENDED_DN_STRING:
02755                 if (!string_to_sid(sid, p)) {
02756                         return False;
02757                 }
02758                 break;
02759         case ADS_EXTENDED_DN_HEX_STRING: {
02760                 pstring buf;
02761                 size_t buf_len;
02762 
02763                 buf_len = strhex_to_str(buf, strlen(p), p);
02764                 if (buf_len == 0) {
02765                         return False;
02766                 }
02767 
02768                 if (!sid_parse(buf, buf_len, sid)) {
02769                         DEBUG(10,("failed to parse sid\n"));
02770                         return False;
02771                 }
02772                 break;
02773                 }
02774         default:
02775                 DEBUG(10,("unknown extended dn format\n"));
02776                 return False;
02777         }
02778 
02779         return True;
02780 }

int ads_pull_sids_from_extendeddn ( ADS_STRUCT ads,
TALLOC_CTX mem_ctx,
LDAPMessage *  msg,
const char *  field,
enum ads_extended_dn_flags  flags,
DOM_SID **  sids 
)

pull an array of DOM_SIDs from a ADS result

引数:
ads connection to ads server
mem_ctx TALLOC_CTX for allocating sid array
msg Results of search
field Attribute to retrieve
flags string type of extended_dn
sids pointer to sid array to allocate
戻り値:
the count of SIDs pulled

ldap.c2792 行で定義されています。

参照先 ads_get_sid_from_extended_dn()ads_pull_strings().

参照元 lookup_usergroups_memberof().

02798 {
02799         int i;
02800         size_t dn_count;
02801         char **dn_strings;
02802 
02803         if ((dn_strings = ads_pull_strings(ads, mem_ctx, msg, field, 
02804                                            &dn_count)) == NULL) {
02805                 return 0;
02806         }
02807 
02808         (*sids) = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, dn_count + 1);
02809         if (!(*sids)) {
02810                 TALLOC_FREE(dn_strings);
02811                 return 0;
02812         }
02813 
02814         for (i=0; i<dn_count; i++) {
02815 
02816                 if (!ads_get_sid_from_extended_dn(mem_ctx, dn_strings[i], 
02817                                                   flags, &(*sids)[i])) {
02818                         TALLOC_FREE(*sids);
02819                         TALLOC_FREE(dn_strings);
02820                         return 0;
02821                 }
02822         }
02823 
02824         TALLOC_FREE(dn_strings);
02825 
02826         return dn_count;
02827 }

char* ads_get_dnshostname ( ADS_STRUCT ads,
TALLOC_CTX ctx,
const char *  machine_name 
)

ldap.c2832 行で定義されています。

参照先 ads_count_replies()ads_find_machine_acct()ads_msgfree()ads_pull_string()global_mynamenamestatus.

参照元 ads_keytab_add_entry().

02833 {
02834         LDAPMessage *res = NULL;
02835         ADS_STATUS status;
02836         int count = 0;
02837         char *name = NULL;
02838         
02839         status = ads_find_machine_acct(ads, &res, global_myname());
02840         if (!ADS_ERR_OK(status)) {
02841                 DEBUG(0,("ads_get_dnshostname: Failed to find account for %s\n",
02842                         global_myname()));
02843                 goto out;
02844         }
02845                 
02846         if ( (count = ads_count_replies(ads, res)) != 1 ) {
02847                 DEBUG(1,("ads_get_dnshostname: %d entries returned!\n", count));
02848                 goto out;
02849         }
02850                 
02851         if ( (name = ads_pull_string(ads, ctx, res, "dNSHostName")) == NULL ) {
02852                 DEBUG(0,("ads_get_dnshostname: No dNSHostName attribute!\n"));
02853         }
02854 
02855 out:
02856         ads_msgfree(ads, res);
02857         
02858         return name;
02859 }

char* ads_get_upn ( ADS_STRUCT ads,
TALLOC_CTX ctx,
const char *  machine_name 
)

ldap.c2864 行で定義されています。

参照先 ads_count_replies()ads_find_machine_acct()ads_msgfree()ads_pull_string()global_mynamenamestatus.

参照元 ads_keytab_create_default().

02865 {
02866         LDAPMessage *res = NULL;
02867         ADS_STATUS status;
02868         int count = 0;
02869         char *name = NULL;
02870         
02871         status = ads_find_machine_acct(ads, &res, global_myname());
02872         if (!ADS_ERR_OK(status)) {
02873                 DEBUG(0,("ads_get_upn: Failed to find account for %s\n",
02874                         global_myname()));
02875                 goto out;
02876         }
02877                 
02878         if ( (count = ads_count_replies(ads, res)) != 1 ) {
02879                 DEBUG(1,("ads_get_upn: %d entries returned!\n", count));
02880                 goto out;
02881         }
02882                 
02883         if ( (name = ads_pull_string(ads, ctx, res, "userPrincipalName")) == NULL ) {
02884                 DEBUG(2,("ads_get_upn: No userPrincipalName attribute!\n"));
02885         }
02886 
02887 out:
02888         ads_msgfree(ads, res);
02889         
02890         return name;
02891 }

char* ads_get_samaccountname ( ADS_STRUCT ads,
TALLOC_CTX ctx,
const char *  machine_name 
)

ldap.c2896 行で定義されています。

参照先 ads_count_replies()ads_find_machine_acct()ads_msgfree()ads_pull_string()global_mynamenamestatus.

参照元 ads_keytab_add_entry()ads_keytab_create_default().

02897 {
02898         LDAPMessage *res = NULL;
02899         ADS_STATUS status;
02900         int count = 0;
02901         char *name = NULL;
02902         
02903         status = ads_find_machine_acct(ads, &res, global_myname());
02904         if (!ADS_ERR_OK(status)) {
02905                 DEBUG(0,("ads_get_dnshostname: Failed to find account for %s\n",
02906                         global_myname()));
02907                 goto out;
02908         }
02909                 
02910         if ( (count = ads_count_replies(ads, res)) != 1 ) {
02911                 DEBUG(1,("ads_get_dnshostname: %d entries returned!\n", count));
02912                 goto out;
02913         }
02914                 
02915         if ( (name = ads_pull_string(ads, ctx, res, "sAMAccountName")) == NULL ) {
02916                 DEBUG(0,("ads_get_dnshostname: No sAMAccountName attribute!\n"));
02917         }
02918 
02919 out:
02920         ads_msgfree(ads, res);
02921         
02922         return name;
02923 }

SAVED CODE we used to join via ldap remember how we did this JRA ADS_STATUS ads_join_realm ( ADS_STRUCT ads,
const char *  machine_name,
uint32  account_type,
const char *  org_unit 
)

Join a machine to a realm Creates the machine account and sets the machine password

引数:
ads connection to ads server
machine name of host to add
org_unit Organizational unit to place machine in
戻り値:
status of join

ldap.c2937 行で定義されています。

参照先 ads_errstr()ads_find_machine_acct()ads_msgfree()statusstrlower_m().

02939 {
02940         ADS_STATUS status;
02941         LDAPMessage *res = NULL;
02942         char *machine;
02943 
02944         /* machine name must be lowercase */
02945         machine = SMB_STRDUP(machine_name);
02946         strlower_m(machine);
02947 
02948         /*
02949         status = ads_find_machine_acct(ads, (void **)&res, machine);
02950         if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) {
02951                 DEBUG(0, ("Host account for %s already exists - deleting old account\n", machine));
02952                 status = ads_leave_realm(ads, machine);
02953                 if (!ADS_ERR_OK(status)) {
02954                         DEBUG(0, ("Failed to delete host '%s' from the '%s' realm.\n",
02955                                 machine, ads->config.realm));
02956                         return status;
02957                 }
02958         }
02959         */
02960         status = ads_add_machine_acct(ads, machine, account_type, org_unit);
02961         if (!ADS_ERR_OK(status)) {
02962                 DEBUG(0, ("ads_join_realm: ads_add_machine_acct failed (%s): %s\n", machine, ads_errstr(status)));
02963                 SAFE_FREE(machine);
02964                 return status;
02965         }
02966 
02967         status = ads_find_machine_acct(ads, (void **)(void *)&res, machine);
02968         if (!ADS_ERR_OK(status)) {
02969                 DEBUG(0, ("ads_join_realm: Host account test failed for machine %s\n", machine));
02970                 SAFE_FREE(machine);
02971                 return status;
02972         }
02973 
02974         SAFE_FREE(machine);
02975         ads_msgfree(ads, res);
02976 
02977         return status;
02978 }

ADS_STATUS ads_leave_realm ( ADS_STRUCT ads,
const char *  hostname 
)

Delete a machine from the realm

引数:
ads connection to ads server
hostname Machine to remove
戻り値:
status of delete

ldap.c2987 行で定義されています。

参照先 ads_count_replies()ads_del_dn()ads_do_search_retry()ads_errstr()ads_find_machine_acct()ads_first_entry()ads_get_dn()ads_memfree()ads_next_entry()hostADS_STRUCT::ldLDAP_SUCCESSstatusstrlower_m().

参照元 net_ads_leave().

02988 {
02989         ADS_STATUS status;
02990         void *msg;
02991         LDAPMessage *res;
02992         char *hostnameDN, *host;
02993         int rc;
02994         LDAPControl ldap_control;
02995         LDAPControl  * pldap_control[2] = {NULL, NULL};
02996 
02997         pldap_control[0] = &ldap_control;
02998         memset(&ldap_control, 0, sizeof(LDAPControl));
02999         ldap_control.ldctl_oid = (char *)LDAP_SERVER_TREE_DELETE_OID;
03000 
03001         /* hostname must be lowercase */
03002         host = SMB_STRDUP(hostname);
03003         strlower_m(host);
03004 
03005         status = ads_find_machine_acct(ads, &res, host);
03006         if (!ADS_ERR_OK(status)) {
03007                 DEBUG(0, ("Host account for %s does not exist.\n", host));
03008                 SAFE_FREE(host);
03009                 return status;
03010         }
03011 
03012         msg = ads_first_entry(ads, res);
03013         if (!msg) {
03014                 SAFE_FREE(host);
03015                 return ADS_ERROR_SYSTEM(ENOENT);
03016         }
03017 
03018         hostnameDN = ads_get_dn(ads, (LDAPMessage *)msg);
03019 
03020         rc = ldap_delete_ext_s(ads->ld, hostnameDN, pldap_control, NULL);
03021         if (rc) {
03022                 DEBUG(3,("ldap_delete_ext_s failed with error code %d\n", rc));
03023         }else {
03024                 DEBUG(3,("ldap_delete_ext_s succeeded with error code %d\n", rc));
03025         }
03026 
03027         if (rc != LDAP_SUCCESS) {
03028                 const char *attrs[] = { "cn", NULL };
03029                 LDAPMessage *msg_sub;
03030 
03031                 /* we only search with scope ONE, we do not expect any further
03032                  * objects to be created deeper */
03033 
03034                 status = ads_do_search_retry(ads, hostnameDN,
03035                                              LDAP_SCOPE_ONELEVEL,
03036                                              "(objectclass=*)", attrs, &res);
03037 
03038                 if (!ADS_ERR_OK(status)) {
03039                         SAFE_FREE(host);
03040                         ads_memfree(ads, hostnameDN);
03041                         return status;
03042                 }
03043 
03044                 for (msg_sub = ads_first_entry(ads, res); msg_sub;
03045                         msg_sub = ads_next_entry(ads, msg_sub)) {
03046 
03047                         char *dn = NULL;
03048 
03049                         if ((dn = ads_get_dn(ads, msg_sub)) == NULL) {
03050                                 SAFE_FREE(host);
03051                                 ads_memfree(ads, hostnameDN);
03052                                 return ADS_ERROR(LDAP_NO_MEMORY);
03053                         }
03054 
03055                         status = ads_del_dn(ads, dn);
03056                         if (!ADS_ERR_OK(status)) {
03057                                 DEBUG(3,("failed to delete dn %s: %s\n", dn, ads_errstr(status)));
03058                                 SAFE_FREE(host);
03059                                 ads_memfree(ads, dn);
03060                                 ads_memfree(ads, hostnameDN);
03061                                 return status;
03062                         }
03063 
03064                         ads_memfree(ads, dn);
03065                 }
03066 
03067                 /* there should be no subordinate objects anymore */
03068                 status = ads_do_search_retry(ads, hostnameDN,
03069                                              LDAP_SCOPE_ONELEVEL,
03070                                              "(objectclass=*)", attrs, &res);
03071 
03072                 if (!ADS_ERR_OK(status) || ( (ads_count_replies(ads, res)) > 0 ) ) {
03073                         SAFE_FREE(host);
03074                         ads_memfree(ads, hostnameDN);
03075                         return status;
03076                 }
03077 
03078                 /* delete hostnameDN now */
03079                 status = ads_del_dn(ads, hostnameDN);
03080                 if (!ADS_ERR_OK(status)) {
03081                         SAFE_FREE(host);
03082                         DEBUG(3,("failed to delete dn %s: %s\n", hostnameDN, ads_errstr(status)));
03083                         ads_memfree(ads, hostnameDN);
03084                         return status;
03085                 }
03086         }
03087 
03088         ads_memfree(ads, hostnameDN);
03089 
03090         status = ads_find_machine_acct(ads, &res, host);
03091         if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) {
03092                 DEBUG(3, ("Failed to remove host account.\n"));
03093                 SAFE_FREE(host);
03094                 return status;
03095         }
03096 
03097         SAFE_FREE(host);
03098         return status;
03099 }


変数

SIG_ATOMIC_T gotalarm [static]

ldap.c45 行で定義されています。


Sambaに対してSat Aug 29 21:23:42 2009に生成されました。  doxygen 1.4.7