2
Unix SMB/CIFS implementation.
3
kerberos utility library
4
Copyright (C) Andrew Tridgell 2001
5
Copyright (C) Remus Koos 2001
6
Copyright (C) Nalin Dahyabhai <nalin@redhat.com> 2004.
7
Copyright (C) Jeremy Allison 2004.
8
Copyright (C) Gerald Carter 2006.
10
This program is free software; you can redistribute it and/or modify
11
it under the terms of the GNU General Public License as published by
12
the Free Software Foundation; either version 3 of the License, or
13
(at your option) any later version.
15
This program is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License
21
along with this program. If not, see <http://www.gnu.org/licenses/>.
29
#define DEFAULT_KRB5_PORT 88
31
#define LIBADS_CCACHE_NAME "MEMORY:libads"
34
we use a prompter to avoid a crash bug in the kerberos libs when
35
dealing with empty passwords
36
this prompter is just a string copy ...
38
static krb5_error_code
39
kerb_prompter(krb5_context ctx, void *data,
43
krb5_prompt prompts[])
45
if (num_prompts == 0) return 0;
47
memset(prompts[0].reply->data, '\0', prompts[0].reply->length);
48
if (prompts[0].reply->length > 0) {
50
strncpy(prompts[0].reply->data, (const char *)data,
51
prompts[0].reply->length-1);
52
prompts[0].reply->length = strlen(prompts[0].reply->data);
54
prompts[0].reply->length = 0;
60
static bool smb_krb5_get_ntstatus_from_krb5_error(krb5_error *error,
64
DATA_BLOB unwrapped_edata;
66
struct KRB5_EDATA_NTSTATUS parsed_edata;
67
enum ndr_err_code ndr_err;
69
#ifdef HAVE_E_DATA_POINTER_IN_KRB5_ERROR
70
edata = data_blob(error->e_data->data, error->e_data->length);
72
edata = data_blob(error->e_data.data, error->e_data.length);
73
#endif /* HAVE_E_DATA_POINTER_IN_KRB5_ERROR */
76
dump_data(10, edata.data, edata.length);
77
#endif /* DEVELOPER */
79
mem_ctx = talloc_init("smb_krb5_get_ntstatus_from_krb5_error");
80
if (mem_ctx == NULL) {
81
data_blob_free(&edata);
85
if (!unwrap_edata_ntstatus(mem_ctx, &edata, &unwrapped_edata)) {
86
data_blob_free(&edata);
91
data_blob_free(&edata);
93
ndr_err = ndr_pull_struct_blob_all(&unwrapped_edata, mem_ctx, NULL,
95
(ndr_pull_flags_fn_t)ndr_pull_KRB5_EDATA_NTSTATUS);
96
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
97
data_blob_free(&unwrapped_edata);
102
data_blob_free(&unwrapped_edata);
105
*nt_status = parsed_edata.ntstatus;
108
TALLOC_FREE(mem_ctx);
113
static bool smb_krb5_get_ntstatus_from_krb5_error_init_creds_opt(krb5_context ctx,
114
krb5_get_init_creds_opt *opt,
118
krb5_error *error = NULL;
120
#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_GET_ERROR
121
ret = krb5_get_init_creds_opt_get_error(ctx, opt, &error);
123
DEBUG(1,("krb5_get_init_creds_opt_get_error gave: %s\n",
124
error_message(ret)));
127
#endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_GET_ERROR */
130
DEBUG(1,("no krb5_error\n"));
134
#ifdef HAVE_E_DATA_POINTER_IN_KRB5_ERROR
135
if (!error->e_data) {
137
if (error->e_data.data == NULL) {
138
#endif /* HAVE_E_DATA_POINTER_IN_KRB5_ERROR */
139
DEBUG(1,("no edata in krb5_error\n"));
140
krb5_free_error(ctx, error);
144
ret = smb_krb5_get_ntstatus_from_krb5_error(error, nt_status);
146
krb5_free_error(ctx, error);
152
simulate a kinit, putting the tgt in the given cache location. If cache_name == NULL
153
place in default cache location.
156
int kerberos_kinit_password_ext(const char *principal,
157
const char *password,
160
time_t *renew_till_time,
161
const char *cache_name,
163
bool add_netbios_addr,
164
time_t renewable_time,
167
krb5_context ctx = NULL;
168
krb5_error_code code = 0;
169
krb5_ccache cc = NULL;
170
krb5_principal me = NULL;
172
krb5_get_init_creds_opt *opt = NULL;
173
smb_krb5_addresses *addr = NULL;
175
ZERO_STRUCT(my_creds);
177
initialize_krb5_error_table();
178
if ((code = krb5_init_context(&ctx)))
181
if (time_offset != 0) {
182
krb5_set_real_time(ctx, time(NULL) + time_offset, 0);
185
DEBUG(10,("kerberos_kinit_password: as %s using [%s] as ccache and config [%s]\n",
187
cache_name ? cache_name: krb5_cc_default_name(ctx),
188
getenv("KRB5_CONFIG")));
190
if ((code = krb5_cc_resolve(ctx, cache_name ? cache_name : krb5_cc_default_name(ctx), &cc))) {
194
if ((code = smb_krb5_parse_name(ctx, principal, &me))) {
198
if ((code = smb_krb5_get_init_creds_opt_alloc(ctx, &opt))) {
202
krb5_get_init_creds_opt_set_renew_life(opt, renewable_time);
203
krb5_get_init_creds_opt_set_forwardable(opt, True);
206
krb5_get_init_creds_opt_set_tkt_life(opt, 60);
209
#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST
211
if ((code = krb5_get_init_creds_opt_set_pac_request(ctx, opt, (krb5_boolean)request_pac))) {
216
if (add_netbios_addr) {
217
if ((code = smb_krb5_gen_netbios_krb5_address(&addr))) {
220
krb5_get_init_creds_opt_set_address_list(opt, addr->addrs);
223
if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password),
224
kerb_prompter, CONST_DISCARD(char *,password),
229
if ((code = krb5_cc_initialize(ctx, cc, me))) {
233
if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
238
*expire_time = (time_t) my_creds.times.endtime;
241
if (renew_till_time) {
242
*renew_till_time = (time_t) my_creds.times.renew_till;
251
*ntstatus = NT_STATUS_OK;
255
/* try to get ntstatus code out of krb5_error when we have it
256
* inside the krb5_get_init_creds_opt - gd */
258
if (opt && smb_krb5_get_ntstatus_from_krb5_error_init_creds_opt(ctx, opt, &status)) {
263
/* fall back to self-made-mapping */
264
*ntstatus = krb5_to_nt_status(code);
268
krb5_free_cred_contents(ctx, &my_creds);
270
krb5_free_principal(ctx, me);
273
smb_krb5_free_addresses(ctx, addr);
276
smb_krb5_get_init_creds_opt_free(ctx, opt);
279
krb5_cc_close(ctx, cc);
282
krb5_free_context(ctx);
289
/* run kinit to setup our ccache */
290
int ads_kinit_password(ADS_STRUCT *ads)
294
const char *account_name;
297
if (ads->auth.flags & ADS_AUTH_USER_CREDS) {
298
account_name = ads->auth.user_name;
299
goto got_accountname;
303
/* this will end up getting a ticket for DOMAIN@RUSTED.REA.LM */
304
account_name = lp_workgroup();
306
/* always use the sAMAccountName for security = domain */
307
/* global_myname()$@REA.LM */
308
if ( lp_security() == SEC_DOMAIN ) {
309
fstr_sprintf( acct_name, "%s$", global_myname() );
310
account_name = acct_name;
313
/* This looks like host/global_myname()@REA.LM */
314
account_name = ads->auth.user_name;
318
if (asprintf(&s, "%s@%s", account_name, ads->auth.realm) == -1) {
319
return KRB5_CC_NOMEM;
322
if (!ads->auth.password) {
324
return KRB5_LIBOS_CANTREADPWD;
327
ret = kerberos_kinit_password_ext(s, ads->auth.password, ads->auth.time_offset,
328
&ads->auth.tgt_expire, NULL, NULL, False, False, ads->auth.renewable,
332
DEBUG(0,("kerberos_kinit_password %s failed: %s\n",
333
s, error_message(ret)));
339
int ads_kdestroy(const char *cc_name)
341
krb5_error_code code;
342
krb5_context ctx = NULL;
343
krb5_ccache cc = NULL;
345
initialize_krb5_error_table();
346
if ((code = krb5_init_context (&ctx))) {
347
DEBUG(3, ("ads_kdestroy: kdb5_init_context failed: %s\n",
348
error_message(code)));
353
if ((code = krb5_cc_default(ctx, &cc))) {
354
krb5_free_context(ctx);
358
if ((code = krb5_cc_resolve(ctx, cc_name, &cc))) {
359
DEBUG(3, ("ads_kdestroy: krb5_cc_resolve failed: %s\n",
360
error_message(code)));
361
krb5_free_context(ctx);
366
if ((code = krb5_cc_destroy (ctx, cc))) {
367
DEBUG(3, ("ads_kdestroy: krb5_cc_destroy failed: %s\n",
368
error_message(code)));
371
krb5_free_context (ctx);
375
/************************************************************************
376
Routine to fetch the salting principal for a service. Active
377
Directory may use a non-obvious principal name to generate the salt
378
when it determines the key to use for encrypting tickets for a service,
379
and hopefully we detected that when we joined the domain.
380
************************************************************************/
382
static char *kerberos_secrets_fetch_salting_principal(const char *service, int enctype)
387
if (asprintf(&key, "%s/%s/enctype=%d",
388
SECRETS_SALTING_PRINCIPAL, service, enctype) == -1) {
391
ret = (char *)secrets_fetch(key, NULL);
396
/************************************************************************
397
Return the standard DES salt key
398
************************************************************************/
400
char* kerberos_standard_des_salt( void )
404
fstr_sprintf( salt, "host/%s.%s@", global_myname(), lp_realm() );
406
fstrcat( salt, lp_realm() );
408
return SMB_STRDUP( salt );
411
/************************************************************************
412
************************************************************************/
414
static char* des_salt_key( void )
418
if (asprintf(&key, "%s/DES/%s", SECRETS_SALTING_PRINCIPAL,
426
/************************************************************************
427
************************************************************************/
429
bool kerberos_secrets_store_des_salt( const char* salt )
434
if ( (key = des_salt_key()) == NULL ) {
435
DEBUG(0,("kerberos_secrets_store_des_salt: failed to generate key!\n"));
440
DEBUG(8,("kerberos_secrets_store_des_salt: deleting salt\n"));
441
secrets_delete( key );
445
DEBUG(3,("kerberos_secrets_store_des_salt: Storing salt \"%s\"\n", salt));
447
ret = secrets_store( key, salt, strlen(salt)+1 );
454
/************************************************************************
455
************************************************************************/
457
char* kerberos_secrets_fetch_des_salt( void )
461
if ( (key = des_salt_key()) == NULL ) {
462
DEBUG(0,("kerberos_secrets_fetch_des_salt: failed to generate key!\n"));
466
salt = (char*)secrets_fetch( key, NULL );
473
/************************************************************************
474
Routine to get the default realm from the kerberos credentials cache.
475
Caller must free if the return value is not NULL.
476
************************************************************************/
478
char *kerberos_get_default_realm_from_ccache( void )
481
krb5_context ctx = NULL;
482
krb5_ccache cc = NULL;
483
krb5_principal princ = NULL;
485
initialize_krb5_error_table();
486
if (krb5_init_context(&ctx)) {
490
DEBUG(5,("kerberos_get_default_realm_from_ccache: "
491
"Trying to read krb5 cache: %s\n",
492
krb5_cc_default_name(ctx)));
493
if (krb5_cc_default(ctx, &cc)) {
494
DEBUG(0,("kerberos_get_default_realm_from_ccache: "
495
"failed to read default cache\n"));
498
if (krb5_cc_get_principal(ctx, cc, &princ)) {
499
DEBUG(0,("kerberos_get_default_realm_from_ccache: "
500
"failed to get default principal\n"));
504
#if defined(HAVE_KRB5_PRINCIPAL_GET_REALM)
505
realm = SMB_STRDUP(krb5_principal_get_realm(ctx, princ));
506
#elif defined(HAVE_KRB5_PRINC_REALM)
508
krb5_data *realm_data = krb5_princ_realm(ctx, princ);
509
realm = SMB_STRNDUP(realm_data->data, realm_data->length);
517
krb5_free_principal(ctx, princ);
520
krb5_cc_close(ctx, cc);
522
krb5_free_context(ctx);
529
/************************************************************************
530
Routine to get the salting principal for this service. This is
531
maintained for backwards compatibilty with releases prior to 3.0.24.
532
Since we store the salting principal string only at join, we may have
533
to look for the older tdb keys. Caller must free if return is not null.
534
************************************************************************/
536
krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context,
537
krb5_principal host_princ,
540
char *unparsed_name = NULL, *salt_princ_s = NULL;
541
krb5_principal ret_princ = NULL;
543
/* lookup new key first */
545
if ( (salt_princ_s = kerberos_secrets_fetch_des_salt()) == NULL ) {
547
/* look under the old key. If this fails, just use the standard key */
549
if (smb_krb5_unparse_name(talloc_tos(), context, host_princ, &unparsed_name) != 0) {
550
return (krb5_principal)NULL;
552
if ((salt_princ_s = kerberos_secrets_fetch_salting_principal(unparsed_name, enctype)) == NULL) {
553
/* fall back to host/machine.realm@REALM */
554
salt_princ_s = kerberos_standard_des_salt();
558
if (smb_krb5_parse_name(context, salt_princ_s, &ret_princ) != 0) {
562
TALLOC_FREE(unparsed_name);
563
SAFE_FREE(salt_princ_s);
568
/************************************************************************
569
Routine to set the salting principal for this service. Active
570
Directory may use a non-obvious principal name to generate the salt
571
when it determines the key to use for encrypting tickets for a service,
572
and hopefully we detected that when we joined the domain.
573
Setting principal to NULL deletes this entry.
574
************************************************************************/
576
bool kerberos_secrets_store_salting_principal(const char *service,
578
const char *principal)
582
krb5_context context = NULL;
583
krb5_principal princ = NULL;
584
char *princ_s = NULL;
585
char *unparsed_name = NULL;
586
krb5_error_code code;
588
if (((code = krb5_init_context(&context)) != 0) || (context == NULL)) {
589
DEBUG(5, ("kerberos_secrets_store_salting_pricipal: kdb5_init_context failed: %s\n",
590
error_message(code)));
593
if (strchr_m(service, '@')) {
594
if (asprintf(&princ_s, "%s", service) == -1) {
598
if (asprintf(&princ_s, "%s@%s", service, lp_realm()) == -1) {
603
if (smb_krb5_parse_name(context, princ_s, &princ) != 0) {
607
if (smb_krb5_unparse_name(talloc_tos(), context, princ, &unparsed_name) != 0) {
611
if (asprintf(&key, "%s/%s/enctype=%d",
612
SECRETS_SALTING_PRINCIPAL, unparsed_name, enctype)
617
if ((principal != NULL) && (strlen(principal) > 0)) {
618
ret = secrets_store(key, principal, strlen(principal) + 1);
620
ret = secrets_delete(key);
627
TALLOC_FREE(unparsed_name);
630
krb5_free_principal(context, princ);
634
krb5_free_context(context);
641
/************************************************************************
642
************************************************************************/
644
int kerberos_kinit_password(const char *principal,
645
const char *password,
647
const char *cache_name)
649
return kerberos_kinit_password_ext(principal,
661
/************************************************************************
662
************************************************************************/
664
static char *print_kdc_line(char *mem_ctx,
665
const char *prev_line,
666
const struct sockaddr_storage *pss)
668
char *kdc_str = NULL;
670
if (pss->ss_family == AF_INET) {
671
kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n",
673
print_canonical_sockaddr(mem_ctx, pss));
675
char addr[INET6_ADDRSTRLEN];
676
uint16_t port = get_sockaddr_port(pss);
678
if (port != 0 && port != DEFAULT_KRB5_PORT) {
679
/* Currently for IPv6 we can't specify a non-default
680
krb5 port with an address, as this requires a ':'.
681
Resolve to a name. */
682
char hostname[MAX_DNS_NAME_LENGTH];
683
int ret = sys_getnameinfo((const struct sockaddr *)pss,
685
hostname, sizeof(hostname),
689
DEBUG(0,("print_kdc_line: can't resolve name "
690
"for kdc with non-default port %s. "
692
print_canonical_sockaddr(mem_ctx, pss),
695
/* Success, use host:port */
696
kdc_str = talloc_asprintf(mem_ctx,
702
kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n",
712
/************************************************************************
713
Create a string list of available kdc's, possibly searching by sitename.
716
If "sitename" is given, the DC's in that site are listed first.
718
************************************************************************/
720
static char *get_kdc_ip_string(char *mem_ctx,
722
const char *sitename,
723
struct sockaddr_storage *pss)
726
struct ip_service *ip_srv_site = NULL;
727
struct ip_service *ip_srv_nonsite = NULL;
730
char *kdc_str = print_kdc_line(mem_ctx, "", pss);
732
if (kdc_str == NULL) {
737
* First get the KDC's only in this site, the rest will be
743
get_kdc_list(realm, sitename, &ip_srv_site, &count_site);
745
for (i = 0; i < count_site; i++) {
746
if (sockaddr_equal((struct sockaddr *)&ip_srv_site[i].ss,
747
(struct sockaddr *)pss)) {
750
/* Append to the string - inefficient
751
* but not done often. */
752
kdc_str = print_kdc_line(mem_ctx,
756
SAFE_FREE(ip_srv_site);
764
get_kdc_list(realm, NULL, &ip_srv_nonsite, &count_nonsite);
766
for (i = 0; i < count_nonsite; i++) {
769
if (sockaddr_equal((struct sockaddr *)&ip_srv_nonsite[i].ss, (struct sockaddr *)pss)) {
773
/* Ensure this isn't an IP already seen (YUK! this is n*n....) */
774
for (j = 0; j < count_site; j++) {
775
if (sockaddr_equal((struct sockaddr *)&ip_srv_nonsite[i].ss,
776
(struct sockaddr *)&ip_srv_site[j].ss)) {
779
/* As the lists are sorted we can break early if nonsite > site. */
780
if (ip_service_compare(&ip_srv_nonsite[i], &ip_srv_site[j]) > 0) {
788
/* Append to the string - inefficient but not done often. */
789
kdc_str = print_kdc_line(mem_ctx,
791
&ip_srv_nonsite[i].ss);
793
SAFE_FREE(ip_srv_site);
794
SAFE_FREE(ip_srv_nonsite);
800
SAFE_FREE(ip_srv_site);
801
SAFE_FREE(ip_srv_nonsite);
803
DEBUG(10,("get_kdc_ip_string: Returning %s\n",
809
/************************************************************************
810
Create a specific krb5.conf file in the private directory pointing
811
at a specific kdc for a realm. Keyed off domain name. Sets
812
KRB5_CONFIG environment variable to point to this file. Must be
813
run as root or will fail (which is a good thing :-).
814
************************************************************************/
816
bool create_local_private_krb5_conf_for_domain(const char *realm,
818
const char *sitename,
819
struct sockaddr_storage *pss)
821
char *dname = lock_path("smb_krb5");
822
char *tmpname = NULL;
824
char *file_contents = NULL;
825
char *kdc_ip_string = NULL;
829
char *realm_upper = NULL;
835
if ((mkdir(dname, 0755)==-1) && (errno != EEXIST)) {
836
DEBUG(0,("create_local_private_krb5_conf_for_domain: "
837
"failed to create directory %s. Error was %s\n",
838
dname, strerror(errno) ));
842
tmpname = lock_path("smb_tmp_krb5.XXXXXX");
847
fname = talloc_asprintf(dname, "%s/krb5.conf.%s", dname, domain);
852
DEBUG(10,("create_local_private_krb5_conf_for_domain: fname = %s, realm = %s, domain = %s\n",
853
fname, realm, domain ));
855
realm_upper = talloc_strdup(fname, realm);
856
strupper_m(realm_upper);
858
kdc_ip_string = get_kdc_ip_string(dname, realm, sitename, pss);
859
if (!kdc_ip_string) {
863
file_contents = talloc_asprintf(fname,
864
"[libdefaults]\n\tdefault_realm = %s\n"
865
"\tdefault_tgs_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n"
866
"\tdefault_tkt_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n"
867
"\tpreferred_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n\n"
868
"[realms]\n\t%s = {\n"
870
realm_upper, realm_upper, kdc_ip_string);
872
if (!file_contents) {
876
flen = strlen(file_contents);
878
fd = smb_mkstemp(tmpname);
880
DEBUG(0,("create_local_private_krb5_conf_for_domain: smb_mkstemp failed,"
881
" for file %s. Errno %s\n",
882
tmpname, strerror(errno) ));
886
if (fchmod(fd, 0644)==-1) {
887
DEBUG(0,("create_local_private_krb5_conf_for_domain: fchmod failed for %s."
889
tmpname, strerror(errno) ));
895
ret = write(fd, file_contents, flen);
897
DEBUG(0,("create_local_private_krb5_conf_for_domain: write failed,"
898
" returned %d (should be %u). Errno %s\n",
899
(int)ret, (unsigned int)flen, strerror(errno) ));
905
DEBUG(0,("create_local_private_krb5_conf_for_domain: close failed."
906
" Errno %s\n", strerror(errno) ));
911
if (rename(tmpname, fname) == -1) {
912
DEBUG(0,("create_local_private_krb5_conf_for_domain: rename "
913
"of %s to %s failed. Errno %s\n",
914
tmpname, fname, strerror(errno) ));
919
DEBUG(5,("create_local_private_krb5_conf_for_domain: wrote "
920
"file %s with realm %s KDC list = %s\n",
921
fname, realm_upper, kdc_ip_string));
923
/* Set the environment variable to this file. */
924
setenv("KRB5_CONFIG", fname, 1);
928
#if defined(OVERWRITE_SYSTEM_KRB5_CONF)
930
#define SYSTEM_KRB5_CONF_PATH "/etc/krb5.conf"
931
/* Insanity, sheer insanity..... */
933
if (strequal(realm, lp_realm())) {
934
char linkpath[PATH_MAX+1];
937
lret = readlink(SYSTEM_KRB5_CONF_PATH, linkpath, sizeof(linkpath)-1);
939
linkpath[lret] = '\0';
942
if (lret != -1 || strcmp(linkpath, fname) == 0) {
943
/* Symlink already exists. */
947
/* Try and replace with a symlink. */
948
if (symlink(fname, SYSTEM_KRB5_CONF_PATH) == -1) {
949
const char *newpath = SYSTEM_KRB5_CONF_PATH ## ".saved";
950
if (errno != EEXIST) {
951
DEBUG(0,("create_local_private_krb5_conf_for_domain: symlink "
952
"of %s to %s failed. Errno %s\n",
953
fname, SYSTEM_KRB5_CONF_PATH, strerror(errno) ));
954
goto done; /* Not a fatal error. */
957
/* Yes, this is a race conditon... too bad. */
958
if (rename(SYSTEM_KRB5_CONF_PATH, newpath) == -1) {
959
DEBUG(0,("create_local_private_krb5_conf_for_domain: rename "
960
"of %s to %s failed. Errno %s\n",
961
SYSTEM_KRB5_CONF_PATH, newpath,
963
goto done; /* Not a fatal error. */
966
if (symlink(fname, SYSTEM_KRB5_CONF_PATH) == -1) {
967
DEBUG(0,("create_local_private_krb5_conf_for_domain: "
968
"forced symlink of %s to /etc/krb5.conf failed. Errno %s\n",
969
fname, strerror(errno) ));
970
goto done; /* Not a fatal error. */
977
TALLOC_FREE(tmpname);