From 19a384a54c678e9e064a79abeb1cfa39f9201896 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 29 Mar 2003 23:30:53 +0000 Subject: updated the TCON test so that win2000 passes. Samba now fails this test. It is an interesting test because it shows that win2000 completely ignores the TID and VUID fields in a SMBwriteX. In Samba it is hard to do this as we check the VUID and TID fields before we call the SMB specific reply functions. The test also shows that the list of open files must be global to the socket, not specific to a tcon. (This used to be commit be98069c4e5bbfbe3ce66c20f796c2d2324e7511) --- source3/torture/torture.c | 95 +++++++++++++++++++++++++++++++---------------- 1 file changed, 63 insertions(+), 32 deletions(-) (limited to 'source3') diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 6ab5bf6dbb..7bf4f10af0 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -902,77 +902,108 @@ static BOOL run_locktest1(int dummy) } /* - checks for correct tconX support + this checks to see if a secondary tconx can use open files from an + earlier tconx */ static BOOL run_tcon_test(int dummy) { - static struct cli_state *cli1; + static struct cli_state *cli; const char *fname = "\\tcontest.tmp"; int fnum1; - uint16 cnum; + uint16 cnum1, cnum2, cnum3; + uint16 vuid1, vuid2; char buf[4]; + BOOL ret = True; - if (!torture_open_connection(&cli1)) { + if (!torture_open_connection(&cli)) { return False; } - cli_sockopt(cli1, sockops); + cli_sockopt(cli, sockops); printf("starting tcontest\n"); - cli_unlink(cli1, fname); + cli_unlink(cli, fname); - fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE); - if (fnum1 == -1) - { - printf("open of %s failed (%s)\n", fname, cli_errstr(cli1)); + fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE); + if (fnum1 == -1) { + printf("open of %s failed (%s)\n", fname, cli_errstr(cli)); return False; } - cnum = cli1->cnum; + cnum1 = cli->cnum; + vuid1 = cli->vuid; - if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) - { - printf("write failed (%s)", cli_errstr(cli1)); + if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) { + printf("initial write failed (%s)", cli_errstr(cli)); return False; } - if (!cli_send_tconX(cli1, share, "?????", + if (!cli_send_tconX(cli, share, "?????", password, strlen(password)+1)) { printf("%s refused 2nd tree connect (%s)\n", host, - cli_errstr(cli1)); - cli_shutdown(cli1); + cli_errstr(cli)); + cli_shutdown(cli); return False; } - if (cli_write(cli1, fnum1, 0, buf, 130, 4) == 4) - { - printf("write succeeded (%s)", cli_errstr(cli1)); - return False; + cnum2 = cli->cnum; + cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */ + vuid2 = cli->vuid + 1; + + /* try a write with the wrong tid */ + cli->cnum = cnum2; + + if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) { + printf("server allows write with wrong TID\n"); + } else { + printf("* server fails write with wrong TID : %s\n", cli_errstr(cli)); + ret = False; } - if (cli_close(cli1, fnum1)) { - printf("close2 succeeded (%s)\n", cli_errstr(cli1)); - return False; + + /* try a write with an invalid tid */ + cli->cnum = cnum3; + + if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) { + printf("server allows write with invalid TID\n"); + } else { + printf("* server fails write with invalid TID : %s\n", cli_errstr(cli)); + ret = False; + } + + /* try a write with an invalid vuid */ + cli->vuid = vuid2; + cli->cnum = cnum1; + + if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) { + printf("server allows write with invalid VUID\n"); + } else { + printf("* server fails write with invalid VUID : %s\n", cli_errstr(cli)); + ret = False; } - if (!cli_tdis(cli1)) { - printf("tdis failed (%s)\n", cli_errstr(cli1)); + cli->cnum = cnum1; + cli->vuid = vuid1; + + if (!cli_close(cli, fnum1)) { + printf("close failed (%s)\n", cli_errstr(cli)); return False; } - cli1->cnum = cnum; + cli->cnum = cnum2; - if (!cli_close(cli1, fnum1)) { - printf("close2 failed (%s)\n", cli_errstr(cli1)); + if (!cli_tdis(cli)) { + printf("secondary tdis failed (%s)\n", cli_errstr(cli)); return False; } - if (!torture_close_connection(cli1)) { + cli->cnum = cnum1; + + if (!torture_close_connection(cli)) { return False; } - printf("Passed tcontest\n"); - return True; + return ret; } -- cgit From 097a7b52e7394f40dd9fd0ec342336f2c819ec12 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 29 Mar 2003 23:55:54 +0000 Subject: fixed the -U option in nmblookup please remember to *test* your changes before committing them. This is especially the case when you receive patches from outside the team - before you commit you must make sure that the patch actually works. (This used to be commit 1d3c7e7fb628a528978f345f83289cc7f2521c35) --- source3/utils/nmblookup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/utils/nmblookup.c b/source3/utils/nmblookup.c index 31c7967a07..d4d43796a0 100644 --- a/source3/utils/nmblookup.c +++ b/source3/utils/nmblookup.c @@ -195,7 +195,7 @@ int main(int argc,char *argv[]) POPT_AUTOHELP { "broadcast", 'b', POPT_ARG_STRING, NULL, 'B', "Specify address to use for broadcasts", "BROADCAST-ADDRESS" }, { "flags", 'f', POPT_ARG_VAL, &give_flags, True, "List the NMB flags returned" }, - { "unicast", 'U', POPT_ARG_NONE, NULL, 'U', "Specify address to use for unicast" }, + { "unicast", 'U', POPT_ARG_STRING, NULL, 'U', "Specify address to use for unicast" }, { "master-browser", 'M', POPT_ARG_VAL, &find_master, True, "Search for a master browser" }, { "recursion", 'R', POPT_ARG_VAL, &recursion_desired, True, "Set recursion desired in package" }, { "status", 'S', POPT_ARG_VAL, &find_status, True, "Lookup node status as well" }, -- cgit From 6fca8cc8a7073f2ee17c3417b42cadc46b3c5195 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 30 Mar 2003 00:00:10 +0000 Subject: fixed the -B option as well (This used to be commit 0c12a206bb6610d79deb89868cac9293604b7c08) --- source3/utils/nmblookup.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3') diff --git a/source3/utils/nmblookup.c b/source3/utils/nmblookup.c index d4d43796a0..d2c5cbc00e 100644 --- a/source3/utils/nmblookup.c +++ b/source3/utils/nmblookup.c @@ -193,7 +193,7 @@ int main(int argc,char *argv[]) struct poptOption long_options[] = { POPT_AUTOHELP - { "broadcast", 'b', POPT_ARG_STRING, NULL, 'B', "Specify address to use for broadcasts", "BROADCAST-ADDRESS" }, + { "broadcast", 'B', POPT_ARG_STRING, NULL, 'B', "Specify address to use for broadcasts", "BROADCAST-ADDRESS" }, { "flags", 'f', POPT_ARG_VAL, &give_flags, True, "List the NMB flags returned" }, { "unicast", 'U', POPT_ARG_STRING, NULL, 'U', "Specify address to use for unicast" }, { "master-browser", 'M', POPT_ARG_VAL, &find_master, True, "Search for a master browser" }, @@ -216,9 +216,8 @@ int main(int argc,char *argv[]) poptSetOtherOptionHelp(pc, " ..."); - while ((opt = poptGetNextOpt(pc)) != -1) - switch (opt) - { + while ((opt = poptGetNextOpt(pc)) != -1) { + switch (opt) { case 'B': bcast_addr = *interpret_addr2(poptGetOptArg(pc)); got_bcast = True; @@ -233,6 +232,7 @@ int main(int argc,char *argv[]) translate_addresses = !translate_addresses; break; } + } poptGetArg(pc); /* Remove argv[0] */ -- cgit From bcd9a08802f9f4f4b68741fb51574d3944cb4040 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 30 Mar 2003 02:52:47 +0000 Subject: Don't modify the incoming packet when checking the signiture. Andrew Bartlett (This used to be commit 7064edf8534a6098fc4990bc516fcb45f4ff44bb) --- source3/libsmb/smb_signing.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) (limited to 'source3') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index c713418e82..9bbf7ef91c 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -79,7 +79,7 @@ static void mark_packet_signed(struct cli_state *cli) static BOOL signing_good(struct cli_state *cli, BOOL good) { DEBUG(10, ("got SMB signature of\n")); - dump_data(10,&cli->outbuf[smb_ss_field] , 8); + dump_data(10,&cli->inbuf[smb_ss_field] , 8); if (good && !cli->sign_info.doing_signing) { cli->sign_info.doing_signing = True; @@ -147,31 +147,47 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) BOOL good; unsigned char calc_md5_mac[16]; unsigned char server_sent_mac[8]; + unsigned char sequence_buf[8]; struct MD5Context md5_ctx; struct smb_basic_signing_context *data = cli->sign_info.signing_context; + const size_t offset_end_of_sig = (smb_ss_field + 8); /* * Firstly put the sequence number into the first 4 bytes. * and zero out the next 4 bytes. */ - memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); - - DEBUG(10, ("got SMB signature of\n")); - dump_data(10, server_sent_mac, 8); + SIVAL(sequence_buf, 0, data->reply_seq_num); + SIVAL(sequence_buf, 4, 0); - SIVAL(cli->inbuf, smb_ss_field, data->reply_seq_num); - SIVAL(cli->inbuf, smb_ss_field + 4, 0); + if (smb_len(cli->inbuf) < (offset_end_of_sig - 4)) { + DEBUG(1, ("Can't check signature on short packet! smb_len = %u\n", smb_len(cli->inbuf))); + return False; + } + /* get a copy of the server-sent mac */ + memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); + /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ MD5Init(&md5_ctx); MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); - MD5Update(&md5_ctx, cli->inbuf + 4, smb_len(cli->inbuf)); + MD5Update(&md5_ctx, cli->inbuf + 4, smb_ss_field - 4); + MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf)); + + MD5Update(&md5_ctx, cli->inbuf + offset_end_of_sig, + smb_len(cli->inbuf) - (offset_end_of_sig - 4)); MD5Final(calc_md5_mac, &md5_ctx); good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); + if (!good) { + DEBUG(5, ("BAD SIG: wanted SMB signature of\n")); + dump_data(5, calc_md5_mac, 8); + + DEBUG(5, ("BAD SIG: got SMB signature of\n")); + dump_data(5, server_sent_mac, 8); + } return signing_good(cli, good); } @@ -213,7 +229,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ memcpy(&data->mac_key.data[0], user_session_key, 16); memcpy(&data->mac_key.data[16],response.data, MIN(response.length, 40 - 16)); - /* Initialize the sequence number */ + /* Initialise the sequence number */ data->send_seq_num = 0; cli->sign_info.sign_outgoing_message = cli_simple_sign_outgoing_message; @@ -348,7 +364,7 @@ static void cli_null_free_signing_context(struct cli_state *cli) SMB signing - NULL implementation - setup the MAC key. @note Used as an initialisation only - it will not correctly - shut down a real signing mechinism + shut down a real signing mechanism */ BOOL cli_null_set_signing(struct cli_state *cli) -- cgit From cb830f05ae4ab5057209fb1b7c68bae450e78b22 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 30 Mar 2003 09:45:44 +0000 Subject: added simple tests for SMBchkpath and SMBioctl (This used to be commit ca982a9f1d6485e2d388d4b2e9c13806736ad91e) --- source3/libsmb/clifile.c | 32 ++++++++++- source3/torture/torture.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 173 insertions(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index d86f36405d..4eb5efe193 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -942,7 +942,6 @@ BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t) /**************************************************************************** Check for existance of a dir. ****************************************************************************/ - BOOL cli_chkpath(struct cli_state *cli, const char *path) { pstring path2; @@ -1049,3 +1048,34 @@ int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path) return SVAL(cli->inbuf,smb_vwv0); } + + +/* + send a raw ioctl - used by the torture code +*/ +NTSTATUS cli_raw_ioctl(struct cli_state *cli, int fnum, uint32 code, DATA_BLOB *blob) +{ + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf, 3, 0, True); + SCVAL(cli->outbuf,smb_com,SMBioctl); + cli_setup_packet(cli); + + SSVAL(cli->outbuf, smb_vwv0, fnum); + SSVAL(cli->outbuf, smb_vwv1, code>>16); + SSVAL(cli->outbuf, smb_vwv2, (code&0xFFFF)); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + + if (cli_is_error(cli)) { + return cli_nt_error(cli); + } + + *blob = data_blob(NULL, 0); + + return NT_STATUS_OK; +} diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 7bf4f10af0..a7607aae6c 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -3873,6 +3873,146 @@ static void del_fn(file_info *finfo, const char *mask, void *state) } } + +/* + sees what IOCTLs are supported + */ +BOOL torture_ioctl_test(int dummy) +{ + static struct cli_state *cli; + uint16 device, function; + int fnum; + const char *fname = "\\ioctl.dat"; + DATA_BLOB blob; + NTSTATUS status; + + if (!torture_open_connection(&cli)) { + return False; + } + + printf("starting ioctl test\n"); + + cli_unlink(cli, fname); + + fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE); + if (fnum == -1) { + printf("open of %s failed (%s)\n", fname, cli_errstr(cli)); + return False; + } + + status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob); + printf("ioctl device info: %s\n", cli_errstr(cli)); + + status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob); + printf("ioctl job info: %s\n", cli_errstr(cli)); + + for (device=0;device<0x100;device++) { + printf("testing device=0x%x\n", device); + for (function=0;function<0x100;function++) { + uint32 code = (device<<16) | function; + + status = cli_raw_ioctl(cli, fnum, code, &blob); + + if (NT_STATUS_IS_OK(status)) { + printf("ioctl 0x%x OK : %d bytes\n", code, blob.length); + data_blob_free(&blob); + } + } + } + + if (!torture_close_connection(cli)) { + return False; + } + + return True; +} + + +/* + tries varients of chkpath + */ +BOOL torture_chkpath_test(int dummy) +{ + static struct cli_state *cli; + int fnum; + BOOL ret; + + if (!torture_open_connection(&cli)) { + return False; + } + + printf("starting chkpath test\n"); + + /* cleanup from an old run */ + cli_rmdir(cli, "\\chkpath.dir\\dir2"); + cli_unlink(cli, "\\chkpath.dir\\*"); + cli_rmdir(cli, "\\chkpath.dir"); + + if (!cli_mkdir(cli, "\\chkpath.dir")) { + printf("mkdir1 failed : %s\n", cli_errstr(cli)); + return False; + } + + if (!cli_mkdir(cli, "\\chkpath.dir\\dir2")) { + printf("mkdir2 failed : %s\n", cli_errstr(cli)); + return False; + } + + fnum = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE); + if (fnum == -1) { + printf("open1 failed (%s)\n", cli_errstr(cli)); + return False; + } + cli_close(cli, fnum); + + if (!cli_chkpath(cli, "\\chkpath.dir")) { + printf("chkpath1 failed: %s\n", cli_errstr(cli)); + ret = False; + } + + if (!cli_chkpath(cli, "\\chkpath.dir\\dir2")) { + printf("chkpath2 failed: %s\n", cli_errstr(cli)); + ret = False; + } + + if (!cli_chkpath(cli, "\\chkpath.dir\\foo.txt")) { + ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath, + NT_STATUS_NOT_A_DIRECTORY); + } else { + printf("* chkpath on a file should fail\n"); + ret = False; + } + + if (!cli_chkpath(cli, "\\chkpath.dir\\bar.txt")) { + ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile, + NT_STATUS_OBJECT_NAME_NOT_FOUND); + } else { + printf("* chkpath on a non existant file should fail\n"); + ret = False; + } + + if (!cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt")) { + ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath, + NT_STATUS_OBJECT_PATH_NOT_FOUND); + } else { + printf("* chkpath on a non existent component should fail\n"); + ret = False; + } + + cli_rmdir(cli, "\\chkpath.dir\\dir2"); + cli_unlink(cli, "\\chkpath.dir\\*"); + cli_rmdir(cli, "\\chkpath.dir"); + + if (!torture_close_connection(cli)) { + return False; + } + + return ret; +} + + + + static BOOL run_dirtest1(int dummy) { int i; @@ -4206,6 +4346,8 @@ static struct { {"ERRMAPEXTRACT", run_error_map_extract, 0}, {"PIPE_NUMBER", run_pipe_number, 0}, {"TCON2", run_tcon2_test, 0}, + {"IOCTL", torture_ioctl_test, 0}, + {"CHKPATH", torture_chkpath_test, 0}, {NULL, NULL, 0}}; -- cgit From 7ea0ef92cbd49db6d7ae0d1e72b8f4f1f1fb7e7c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 30 Mar 2003 12:42:18 +0000 Subject: - Point users at the HOWTO Collection instead of 'README' in modules/mysql.c - Make passdb work with absolute paths (passdb backend = /path/to/smbpasswd.so works now). vfs, rpc and charset will follow (This used to be commit 794d3ed03619a4e41558d9ff65783a1aa1b2be90) --- source3/lib/module.c | 28 ++++++++++++++++++++++++++-- source3/modules/mysql.c | 2 +- source3/passdb/pdb_interface.c | 5 ++++- source3/utils/pdbedit.c | 2 -- 4 files changed, 31 insertions(+), 6 deletions(-) (limited to 'source3') diff --git a/source3/lib/module.c b/source3/lib/module.c index bf37078bb9..e400945a8b 100644 --- a/source3/lib/module.c +++ b/source3/lib/module.c @@ -80,7 +80,7 @@ int smb_probe_module(const char *subsystem, const char *module) pstring full_path; /* Check for absolute path */ - if(module[0] == '/')return smb_load_module(module); + if(strchr_m(module, '/'))return smb_load_module(module); pstrcpy(full_path, lib_path(subsystem)); pstrcat(full_path, "/"); @@ -117,7 +117,31 @@ int smb_probe_module(const char *subsystem, const char *module) void init_modules(void) { + /* FIXME: This can cause undefined symbol errors : + * smb_register_vfs() isn't available in nmbd, for example */ if(lp_preload_modules()) smb_load_modules(lp_preload_modules()); - /* FIXME: load static modules */ +} + + +/************************************************************************* + * This functions /path/to/foobar.so -> foobar + ************************************************************************/ +void module_path_get_name(char *path, pstring name) +{ + char *s; + + /* First, make the path relative */ + s = strrchr_m(path, '/'); + if(s) pstrcpy(name, s+1); + else pstrcpy(name, path); + + if (dyn_SHLIBEXT && *dyn_SHLIBEXT && strlen(dyn_SHLIBEXT) < strlen(name)) { + int n = strlen(name) - strlen(dyn_SHLIBEXT); + + /* Remove extension if necessary */ + if (name[n-1] == '.' && !strcmp(name+n, dyn_SHLIBEXT)) { + name[n-1] = '\0'; + } + } } diff --git a/source3/modules/mysql.c b/source3/modules/mysql.c index 40694d6e7d..684eb96645 100644 --- a/source3/modules/mysql.c +++ b/source3/modules/mysql.c @@ -933,7 +933,7 @@ static NTSTATUS mysqlsam_init(struct pdb_context * pdb_context, struct pdb_metho data->pwent = NULL; if (!location) { - DEBUG(0, ("No identifier specified. See README for details\n")); + DEBUG(0, ("No identifier specified. Check the Samba HOWTO Collection for details\n")); return NT_STATUS_INVALID_PARAMETER; } diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 4d9ec7beea..95f587b076 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -64,9 +64,12 @@ BOOL smb_register_passdb(const char *name, pdb_init_function init, int version) struct pdb_init_function_entry *pdb_find_backend_entry(const char *name) { struct pdb_init_function_entry *entry = backends; + pstring stripped; + + module_path_get_name(name, stripped); while(entry) { - if (strequal(entry->name, name)) return entry; + if (strequal(entry->name, stripped)) return entry; entry = entry->next; } diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index f33dbd9f1c..bf42fb805f 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -563,8 +563,6 @@ int main (int argc, char **argv) exit(1); } - init_modules(); - if (!init_names()) exit(1); -- cgit From 17d188d99971ab0e9a61aecef4ed29c7925aac3c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 30 Mar 2003 16:36:21 +0000 Subject: This changes our handling of invalid service types that the client requested on tconx. We now return the same error code like NT4SP6 and W2kSP3 return. TCONDEV is a little test for this. Volker (This used to be commit 6ab88f31d6773f16baff8421ec9e530461cc8f93) --- source3/smbd/service.c | 19 +++++---- source3/torture/torture.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 7 deletions(-) (limited to 'source3') diff --git a/source3/smbd/service.c b/source3/smbd/service.c index f67361e66a..5c87eb0729 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -227,22 +227,27 @@ static NTSTATUS share_sanity_checks(int snum, fstring dev) return NT_STATUS_ACCESS_DENIED; } - /* you can only connect to the IPC$ service as an ipc device */ - if (strequal(lp_fstype(snum), "IPC")) - fstrcpy(dev,"IPC"); - if (dev[0] == '?' || !dev[0]) { if (lp_print_ok(snum)) { fstrcpy(dev,"LPT1:"); + } else if (strequal(lp_fstype(snum), "IPC")) { + fstrcpy(dev, "IPC"); } else { fstrcpy(dev,"A:"); } } - /* if the request is as a printer and you can't print then refuse */ strupper(dev); - if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) { - DEBUG(1,("Attempt to connect to non-printer as a printer\n")); + + if (lp_print_ok(snum)) { + if (!strequal(dev, "LPT:")) { + return NT_STATUS_BAD_DEVICE_TYPE; + } + } else if (strequal(lp_fstype(snum), "IPC")) { + if (!strequal(dev, "IPC")) { + return NT_STATUS_BAD_DEVICE_TYPE; + } + } else if (!strequal(dev, "A:")) { return NT_STATUS_BAD_DEVICE_TYPE; } diff --git a/source3/torture/torture.c b/source3/torture/torture.c index a7607aae6c..d6ae58c522 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -1043,6 +1043,105 @@ static BOOL run_tcon2_test(int dummy) return True; } +static BOOL tcon_devtest(struct cli_state *cli, + const char *myshare, const char *devtype, + NTSTATUS expected_error) +{ + BOOL status; + BOOL ret; + + status = cli_send_tconX(cli, myshare, devtype, + password, strlen(password)+1); + + if (NT_STATUS_IS_OK(expected_error)) { + if (status) { + ret = True; + } else { + printf("tconX to share %s with type %s " + "should have succeeded but failed\n", + myshare, devtype); + ret = False; + } + cli_tdis(cli); + } else { + if (status) { + printf("tconx to share %s with type %s " + "should have failed but succeeded\n", + myshare, devtype); + ret = False; + } else { + if (NT_STATUS_EQUAL(cli_nt_error(cli), + expected_error)) { + ret = True; + } else { + printf("Returned unexpected error\n"); + ret = False; + } + } + } + return ret; +} + +/* + checks for correct tconX support + */ +static BOOL run_tcon_devtype_test(int dummy) +{ + static struct cli_state *cli1 = NULL; + BOOL retry; + int flags = 0; + NTSTATUS status; + BOOL ret; + + status = cli_full_connection(&cli1, myname, + host, NULL, port_to_use, + NULL, NULL, + username, workgroup, + password, flags, &retry); + + if (!NT_STATUS_IS_OK(status)) { + printf("could not open connection\n"); + return False; + } + + if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE)) + ret = False; + + if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK)) + ret = False; + + if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE)) + ret = False; + + if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK)) + ret = False; + + if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE)) + ret = False; + + if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK)) + ret = False; + + if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK)) + ret = False; + + if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE)) + ret = False; + + if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE)) + ret = False; + + if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE)) + ret = False; + + cli_shutdown(cli1); + + if (ret) + printf("Passed tcondevtest\n"); + + return ret; +} + /* This test checks that @@ -4326,6 +4425,7 @@ static struct { {"DENY1", torture_denytest1, 0}, {"DENY2", torture_denytest2, 0}, {"TCON", run_tcon_test, 0}, + {"TCONDEV", run_tcon_devtype_test, 0}, {"RW1", run_readwritetest, 0}, {"RW2", run_readwritemulti, FLAG_MULTIPROC}, {"RW3", run_readwritelarge, 0}, -- cgit From 332f6f9513b04bf7a4ab8223f401b000d8e2c64b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 30 Mar 2003 16:40:13 +0000 Subject: This fixes group updates in LDAP the same way as user updates are handled, though we assume that always everything needs to be updated in LDAP. PDB_IS_* is not done yet for groups. Do we need it? Volker (This used to be commit 409a26282f8fcbd583a85df40c70b504eac26f6e) --- source3/passdb/pdb_ldap.c | 175 ++++++++++++++++++++++++++-------------------- 1 file changed, 98 insertions(+), 77 deletions(-) (limited to 'source3') diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 226c1fc171..8a74cc1f67 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -1301,18 +1301,10 @@ static BOOL need_ldap_mod(BOOL pdb_add, const SAM_ACCOUNT * sampass, enum pdb_el *********************************************************************/ static void make_ldap_mod(LDAP *ldap_struct, LDAPMessage *existing, LDAPMod ***mods, - const SAM_ACCOUNT *sampass, - BOOL (*need_update)(const SAM_ACCOUNT *, - enum pdb_elements), - enum pdb_elements element, const char *attribute, const char *newval) { char **values = NULL; - if (!need_update(sampass, element)) { - return; - } - if (existing != NULL) { values = ldap_get_values(ldap_struct, existing, attribute); } @@ -1376,8 +1368,10 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, * took out adding "objectclass: sambaAccount" * do this on a per-mod basis */ - make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update, - PDB_USERNAME, "uid", pdb_get_username(sampass)); + if (need_update(sampass, PDB_USERNAME)) + make_ldap_mod(ldap_state->ldap_struct, existing, mods, + "uid", pdb_get_username(sampass)); + DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass))); rid = pdb_get_user_rid(sampass); @@ -1404,8 +1398,10 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, } slprintf(temp, sizeof(temp) - 1, "%i", rid); - make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update, - PDB_USERSID, "rid", temp); + + if (need_update(sampass, PDB_USERSID)) + make_ldap_mod(ldap_state->ldap_struct, existing, mods, + "rid", temp); rid = pdb_get_group_rid(sampass); @@ -1424,8 +1420,10 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, } slprintf(temp, sizeof(temp) - 1, "%i", rid); - make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update, - PDB_GROUPSID, "primaryGroupID", temp); + + if (need_update(sampass, PDB_GROUPSID)) + make_ldap_mod(ldap_state->ldap_struct, existing, mods, + "primaryGroupID", temp); /* displayName, cn, and gecos should all be the same * most easily accomplished by giving them the same OID @@ -1435,81 +1433,100 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, * it does not exist. */ - make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update, - PDB_FULLNAME, "displayName", - pdb_get_fullname(sampass)); + if (need_update(sampass, PDB_FULLNAME)) + make_ldap_mod(ldap_state->ldap_struct, existing, mods, + "displayName", pdb_get_fullname(sampass)); - make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update, - PDB_ACCTDESC, "description", - pdb_get_acct_desc(sampass)); + if (need_update(sampass, PDB_ACCTDESC)) + make_ldap_mod(ldap_state->ldap_struct, existing, mods, + "description", pdb_get_acct_desc(sampass)); - make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update, - PDB_WORKSTATIONS, "userWorkstations", - pdb_get_workstations(sampass)); + if (need_update(sampass, PDB_WORKSTATIONS)) + make_ldap_mod(ldap_state->ldap_struct, existing, mods, + "userWorkstations", pdb_get_workstations(sampass)); - make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update, - PDB_SMBHOME, "smbHome", - pdb_get_homedir(sampass)); + if (need_update(sampass, PDB_SMBHOME)) + make_ldap_mod(ldap_state->ldap_struct, existing, mods, + "smbHome", pdb_get_homedir(sampass)); - make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update, - PDB_DRIVE, "homeDrive", - pdb_get_dir_drive(sampass)); + if (need_update(sampass, PDB_DRIVE)) + make_ldap_mod(ldap_state->ldap_struct, existing, mods, + "homeDrive", pdb_get_dir_drive(sampass)); - make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update, - PDB_LOGONSCRIPT, "scriptPath", - pdb_get_logon_script(sampass)); + if (need_update(sampass, PDB_LOGONSCRIPT)) + make_ldap_mod(ldap_state->ldap_struct, existing, mods, + "scriptPath", pdb_get_logon_script(sampass)); - make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update, - PDB_PROFILE, "profilePath", - pdb_get_profile_path(sampass)); + if (need_update(sampass, PDB_PROFILE)) + make_ldap_mod(ldap_state->ldap_struct, existing, mods, + "profilePath", pdb_get_profile_path(sampass)); slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass)); - make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update, - PDB_LOGONTIME, "logonTime", temp); + + if (need_update(sampass, PDB_LOGONTIME)) + make_ldap_mod(ldap_state->ldap_struct, existing, mods, + "logonTime", temp); slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass)); - make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update, - PDB_LOGOFFTIME, "logoffTime", temp); + + if (need_update(sampass, PDB_LOGOFFTIME)) + make_ldap_mod(ldap_state->ldap_struct, existing, mods, + "logoffTime", temp); slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_kickoff_time(sampass)); - make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update, - PDB_KICKOFFTIME, "kickoffTime", temp); + + if (need_update(sampass, PDB_KICKOFFTIME)) + make_ldap_mod(ldap_state->ldap_struct, existing, mods, + "kickoffTime", temp); slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass)); - make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update, - PDB_CANCHANGETIME, "pwdCanChange", temp); + + if (need_update(sampass, PDB_CANCHANGETIME)) + make_ldap_mod(ldap_state->ldap_struct, existing, mods, + "pwdCanChange", temp); slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_must_change_time(sampass)); - make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update, - PDB_MUSTCHANGETIME, "pwdMustChange", temp); + + if (need_update(sampass, PDB_MUSTCHANGETIME)) + make_ldap_mod(ldap_state->ldap_struct, existing, mods, + "pwdMustChange", temp); if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))|| (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) { pdb_sethexpwd (temp, pdb_get_lanman_passwd(sampass), pdb_get_acct_ctrl(sampass)); - make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update, - PDB_LMPASSWD, "lmPassword", temp); + + if (need_update(sampass, PDB_LMPASSWD)) + make_ldap_mod(ldap_state->ldap_struct, existing, mods, + "lmPassword", temp); pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass), pdb_get_acct_ctrl(sampass)); - make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update, - PDB_NTPASSWD, "ntPassword", temp); + + if (need_update(sampass, PDB_NTPASSWD)) + make_ldap_mod(ldap_state->ldap_struct, existing, mods, + "ntPassword", temp); slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass)); - make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update, - PDB_PASSLASTSET, "pwdLastSet", temp); + + if (need_update(sampass, PDB_PASSLASTSET)) + make_ldap_mod(ldap_state->ldap_struct, existing, mods, + "pwdLastSet", temp); } /* FIXME: Hours stuff goes in LDAP */ - make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update, - PDB_ACCTCTRL, "acctFlags", - pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), - NEW_PW_FORMAT_SPACE_PADDED_LEN)); + + if (need_update(sampass, PDB_ACCTCTRL)) + make_ldap_mod(ldap_state->ldap_struct, existing, mods, + "acctFlags", + pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), + NEW_PW_FORMAT_SPACE_PADDED_LEN)); + return True; } @@ -2252,8 +2269,9 @@ static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state, return True; } -static BOOL init_ldap_from_group(struct ldapsam_privates *ldap_state, - LDAPMod ***mods, int ldap_op, +static BOOL init_ldap_from_group(LDAP *ldap_struct, + LDAPMessage *existing, + LDAPMod ***mods, const GROUP_MAP *map) { pstring tmp; @@ -2266,13 +2284,12 @@ static BOOL init_ldap_from_group(struct ldapsam_privates *ldap_state, *mods = NULL; sid_to_string(tmp, &map->sid); - make_a_mod(mods, ldap_op, "ntSid", tmp); - + make_ldap_mod(ldap_struct, existing, mods, "ntSid", tmp); snprintf(tmp, sizeof(tmp)-1, "%i", map->sid_name_use); - make_a_mod(mods, ldap_op, "ntGroupType", tmp); + make_ldap_mod(ldap_struct, existing, mods, "ntGroupType", tmp); - make_a_mod(mods, ldap_op, "displayName", map->nt_name); - make_a_mod(mods, ldap_op, "description", map->comment); + make_ldap_mod(ldap_struct, existing, mods, "displayName", map->nt_name); + make_ldap_mod(ldap_struct, existing, mods, "description", map->comment); return True; } @@ -2411,14 +2428,17 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods, tmp = ldap_get_dn(ldap_state->ldap_struct, entry); pstrcpy(dn, tmp); ldap_memfree(tmp); - ldap_msgfree(result); - if (!init_ldap_from_group(ldap_state, &mods, LDAP_MOD_ADD, map)) { + if (!init_ldap_from_group(ldap_state->ldap_struct, + result, &mods, map)) { DEBUG(0, ("init_ldap_from_group failed!\n")); ldap_mods_free(mods, 1); + ldap_msgfree(result); return NT_STATUS_UNSUCCESSFUL; } + ldap_msgfree(result); + if (mods == NULL) { DEBUG(0, ("mods is empty\n")); return NT_STATUS_UNSUCCESSFUL; @@ -2455,33 +2475,34 @@ static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods, LDAPMessage *entry; LDAPMod **mods; - if (!init_ldap_from_group(ldap_state, &mods, LDAP_MOD_REPLACE, map)) { - DEBUG(0, ("init_ldap_from_group failed\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - if (mods == NULL) { - DEBUG(4, ("mods is empty: nothing to do\n")); - return NT_STATUS_UNSUCCESSFUL; - } - rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result); if (rc != LDAP_SUCCESS) { - ldap_mods_free(mods, 1); return NT_STATUS_UNSUCCESSFUL; } if (ldap_count_entries(ldap_state->ldap_struct, result) == 0) { DEBUG(0, ("No group to modify!\n")); ldap_msgfree(result); - ldap_mods_free(mods, 1); return NT_STATUS_UNSUCCESSFUL; } entry = ldap_first_entry(ldap_state->ldap_struct, result); dn = ldap_get_dn(ldap_state->ldap_struct, entry); - ldap_msgfree(result); + + if (!init_ldap_from_group(ldap_state->ldap_struct, + result, &mods, map)) { + DEBUG(0, ("init_ldap_from_group failed\n")); + ldap_msgfree(result); + return NT_STATUS_UNSUCCESSFUL; + } + + ldap_msgfree(result); + + if (mods == NULL) { + DEBUG(4, ("mods is empty: nothing to do\n")); + return NT_STATUS_UNSUCCESSFUL; + } rc = ldapsam_modify(ldap_state, dn, mods); -- cgit From ad7364c8405a82c17e6ae238f7fecf843be829cd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 30 Mar 2003 16:46:28 +0000 Subject: This sets the domain for the user in vampire. Otherwise we end up with an empty domain field, which a workstation does not really like in sam_logon.. Volker (This used to be commit e0cb325b99e09a5a5cba07f0403ed445814bbf53) --- source3/utils/net_rpc_samsync.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3') diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index 7460767672..33f4e4b915 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -393,6 +393,8 @@ sam_account_from_delta(SAM_ACCOUNT *account, SAM_ACCOUNT_INFO *delta) if (pdb_get_acct_ctrl(account) != delta->acb_info) pdb_set_acct_ctrl(account, delta->acb_info, PDB_CHANGED); + pdb_set_domain(account, lp_workgroup(), PDB_CHANGED); + return NT_STATUS_OK; } -- cgit From aef719f753c5cdfcacb33653ed0ca0f22b7cf8ea Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 30 Mar 2003 21:23:01 +0000 Subject: Fix installation of auth and charset modules (reported by Stephan Kulow) (This used to be commit 2a281784c95854e13076b21f8043cd624063d461) --- source3/Makefile.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index 9aca82571f..734c380aa8 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1097,8 +1097,8 @@ installmodules: all modules installdirs @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(VFSLIBDIR) $(VFS_MODULES) @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(PDBLIBDIR) $(PDB_MODULES) @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(RPCLIBDIR) $(RPC_MODULES) - @$(SHEEL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(CHARSETLIBDIR) $(CHARSET_MODULES) - @$(SHEEL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(AUTHLIBDIR) $(AUTH_MODULES) + @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(CHARSETLIBDIR) $(CHARSET_MODULES) + @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(AUTHLIBDIR) $(AUTH_MODULES) installscripts: installdirs @$(SHELL) $(srcdir)/script/installscripts.sh $(INSTALLPERMS) $(DESTDIR)$(BINDIR) $(SCRIPTS) -- cgit From 750468d427d554d1968a77bcd4948919c2a3946d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sun, 30 Mar 2003 23:03:27 +0000 Subject: update copyright notice since it we are now almost 4 months into 2003 (This used to be commit 6a17c23a549e1e2ce2b428421fbf0b81b37ad0c1) --- source3/nmbd/nmbd.c | 2 +- source3/smbd/server.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index d013b79d3e..013ef9ddb7 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -654,7 +654,7 @@ static BOOL open_sockets(BOOL isdaemon, int port) reopen_logs(); DEBUG( 0, ( "Netbios nameserver version %s started.\n", VERSION ) ); - DEBUGADD( 0, ( "Copyright Andrew Tridgell and the Samba Team 1994-2002\n" ) ); + DEBUGADD( 0, ( "Copyright Andrew Tridgell and the Samba Team 1994-2003\n" ) ); if ( !reload_nmbd_services(False) ) return(-1); diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 7848e71db2..9d43db20c6 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -755,7 +755,7 @@ static BOOL init_structs(void ) reopen_logs(); DEBUG(0,( "smbd version %s started.\n", VERSION)); - DEBUGADD(0,( "Copyright Andrew Tridgell and the Samba Team 1992-2002\n")); + DEBUGADD(0,( "Copyright Andrew Tridgell and the Samba Team 1992-2003\n")); DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n", (int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid())); -- cgit From f60980b3f250518da85df3680ecb7de7bc13cf00 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 30 Mar 2003 23:44:22 +0000 Subject: distclean fixups from Paul Green. (This used to be commit 3776840227104b1d7d3b7aeceba5d84ded6cfeec) --- source3/Makefile.in | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index 734c380aa8..d9e29ed7b1 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -129,6 +129,8 @@ TORTURE_PROGS = bin/smbtorture@EXEEXT@ bin/msgtest@EXEEXT@ \ BIN_PROGS = $(BIN_PROGS1) $(BIN_PROGS2) $(BIN_PROGS3) @EXTRA_BIN_PROGS@ +EVERYTHING_PROGS = bin/debug2html@EXEEXT@ bin/smbfilter@EXEEXT@ bin/talloctort@EXEEXT@ + SHLIBS = @SHLIB_PROGS@ @LIBSMBCLIENT@ SCRIPTS = $(srcdir)/script/smbtar $(srcdir)/script/addtosmbpass $(srcdir)/script/convert_smbpasswd \ @@ -1184,7 +1186,8 @@ TOPFILES=dynconfig.o dynconfig.po clean: delheaders python_clean -rm -f core */*~ *~ */*.o */*.po */*.po32 */*.@SHLIBEXT@ \ - $(TOPFILES) $(BIN_PROGS) $(SBIN_PROGS) $(MODULES) $(TORTURE_PROGS) $(LIBSMBCLIENT) .headers.stamp + $(TOPFILES) $(BIN_PROGS) $(SBIN_PROGS) $(MODULES) $(TORTURE_PROGS) \ + $(LIBSMBCLIENT) $(EVERYTHING_PROGS) .headers.stamp # This is quite ugly actually.. But we need to make # sure the changes to include/config.h are used. @@ -1279,7 +1282,7 @@ ctags: ctags `find $(srcdir) -name "*.[ch]" | grep -v /CVS/` realclean: clean delheaders - -rm -f config.log $(BIN_PROGS) $(MODULES) $(SBIN_PROGS) bin/.dummy script/findsmb + -rm -f config.log bin/.dummy script/findsmb distclean: realclean -rm -f include/stamp-h -- cgit From 47f230b761f33210beab7f632e8ed1f111959aba Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 31 Mar 2003 01:00:34 +0000 Subject: add a few error checks in EnumPrinterData() (This used to be commit 453813ec6e2c25a3f6a664212aedcad15cfd6000) --- source3/rpc_server/srv_spoolss_nt.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source3') diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 36ff92e46f..99711cbb13 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -7572,7 +7572,7 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S Printer_entry *Printer = find_printer_index_by_hnd(p, handle); int snum; WERROR result; - REGISTRY_VALUE *val; + REGISTRY_VALUE *val = NULL; NT_PRINTER_DATA *p_data; int i, key_index, num_values; int name_length; @@ -7610,7 +7610,7 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S * cf: MSDN EnumPrinterData remark section */ - if ( !in_value_len && !in_data_len ) + if ( !in_value_len && !in_data_len && (key_index != -1) ) { DEBUGADD(6,("Activating NT mega-hack to find sizes\n")); @@ -7650,8 +7650,9 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S * the value len is wrong in NT sp3 * that's the number of bytes not the number of unicode chars */ - - val = regval_ctr_specific_value( &p_data->keys[key_index].values, idx ); + + if ( key_index != -1 ) + val = regval_ctr_specific_value( &p_data->keys[key_index].values, idx ); if ( !val ) { -- cgit From ea279249c9e20081bdb34080c2fa3b8b46c13896 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 31 Mar 2003 01:08:59 +0000 Subject: Don't try and dlsym or dlclose a NULL pointer. The new modules system does not always dlopen() it's modules, and when it does, it keeps them open for the life of the server, not the life of the connection. This caused a segfault on every tree disconnect! Andrew Bartlett (This used to be commit c76ecbae6295022d031d2e286f2d67e5d08946a2) --- source3/smbd/conn.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'source3') diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c index 38fa2e0237..2a77e23e73 100644 --- a/source3/smbd/conn.c +++ b/source3/smbd/conn.c @@ -201,15 +201,18 @@ void conn_free(connection_struct *conn) /* Free vfs_connection_struct */ handle = conn->vfs_private; while(handle) { - /* Close dlopen() handle */ - done_fptr = (void (*)(connection_struct *))sys_dlsym(handle->handle, "vfs_done"); - - if (done_fptr == NULL) { - DEBUG(3, ("No vfs_done() symbol found in module with handle %p, ignoring\n", handle->handle)); - } else { - done_fptr(conn); - } - sys_dlclose(handle->handle); + if (handle->handle) { + /* Close dlopen() handle */ + done_fptr = (void (*)(connection_struct *))sys_dlsym(handle->handle, "vfs_done"); + + if (done_fptr == NULL) { + DEBUG(3, ("No vfs_done() symbol found in module with handle %p, ignoring\n", handle->handle)); + } else { + done_fptr(conn); + } + sys_dlclose(handle->handle); + } + DLIST_REMOVE(conn->vfs_private, handle); thandle = handle->next; SAFE_FREE(handle); -- cgit From 663e5a380cfcab97b24efd3ebbb2869516953023 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 31 Mar 2003 01:30:19 +0000 Subject: Success is not a level-0 issue... Andrew Bartlett (This used to be commit 54e736e6f46a8db6db64a1025daa33fffcbde799) --- source3/smbd/vfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 3dc55cf536..119e2e2f9a 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -267,7 +267,7 @@ BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object) (smb_probe_module("vfs", vfs_object) && (entry = vfs_find_backend_entry(vfs_object)))) { - DEBUG(0,("Successfully loaded %s with the new modules system\n", vfs_object)); + DEBUG(3,("Successfully loaded %s with the new modules system\n", vfs_object)); if ((ops = entry->init(&conn->vfs_ops, conn->vfs_private)) == NULL) { DEBUG(0, ("vfs init function from %s failed\n", vfs_object)); -- cgit From 4b664cfccbb5defa1088e897b012b939c3d99ca9 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 31 Mar 2003 01:44:42 +0000 Subject: Break the current build dependency on perl. Perl is required for include/tdbsam2_parse_info.h which is included by sam/gumm_tdb.c which doesn't seem to be used anywhere. It would be nice to have the tdbsam2 stuff hidden behind a --with configuration parameter so it doesn't interfere with normal builds. (One of the build farm machines doesn't have perl installed). (This used to be commit 58924582e8bb922680860a13a89381b44906e9bc) --- source3/Makefile.in | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index d9e29ed7b1..f712d99693 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -21,6 +21,7 @@ LDSHFLAGS=@LDSHFLAGS@ @LDFLAGS@ @CFLAGS@ AWK=@AWK@ DYNEXP=@DYNEXP@ PYTHON=@PYTHON@ +PERL=@PERL@ TERMLDFLAGS=@TERMLDFLAGS@ TERMLIBS=@TERMLIBS@ @@ -1253,9 +1254,13 @@ utils/net_proto.h: $(NET_OBJ1) include/tdbsam2_parse_info.h: - @cd $(srcdir) && @PERL@ -w script/genstruct.pl \ - -o include/tdbsam2_parse_info.h $(CC) -E -O2 -g \ - include/tdbsam2.h + @if test -n "$(PERL)"; then \ + cd $(srcdir) && @PERL@ -w script/genstruct.pl \ + -o include/tdbsam2_parse_info.h $(CC) -E -O2 -g \ + include/tdbsam2.h; \ + else \ + echo Unable to build $@, continuing; \ + fi # "make headers" or "make proto" calls a subshell because we need to # make sure these commands are executed in sequence even for a -- cgit From 8b48212245a7fc5ccb3d3f60d0cd6ee5c02ba340 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 31 Mar 2003 02:30:49 +0000 Subject: NT4 is particularly fussy about getting this right. Andrew Bartlett (This used to be commit 055a499afb0cab87529f3f991765af95f11cc364) --- source3/smbd/reply.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3') diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 70f5e0aba2..c4e95b7562 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -292,7 +292,6 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt STR_TERMINATE|STR_ASCII); p += srvstr_push(outbuf, p, fsname, -1, STR_TERMINATE); - p = smb_buf(outbuf); set_message_end(outbuf,p); /* what does setting this bit do? It is set by NT4 and -- cgit From 6c33130c0fe78616050e83dcdc9303646636ecca Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 31 Mar 2003 04:36:01 +0000 Subject: Cleanup of winbind client side code. Mostly this consists of untangling the existing code and moving it in to operating system specific files. The winbind client code for all supported operating systems is now in nsswitch/winbind_nss_OSNAME.[ch] to make things a bit clearer. (This used to be commit 93ea047a16a292b23a1d8736ce9bc4098ba142ba) --- source3/Makefile.in | 3 +- source3/configure.in | 10 +- source3/include/includes.h | 2 +- source3/nsswitch/hp_nss_common.h | 51 -- source3/nsswitch/hp_nss_dbdefs.h | 105 --- source3/nsswitch/nss.h | 104 --- source3/nsswitch/wb_client.c | 2 +- source3/nsswitch/winbind_nss.c | 1341 -------------------------------- source3/nsswitch/winbind_nss.h | 71 ++ source3/nsswitch/winbind_nss_config.h | 25 +- source3/nsswitch/winbind_nss_hpux.h | 141 ++++ source3/nsswitch/winbind_nss_irix.c | 515 ++++++++++++ source3/nsswitch/winbind_nss_irix.h | 48 ++ source3/nsswitch/winbind_nss_linux.c | 862 ++++++++++++++++++++ source3/nsswitch/winbind_nss_linux.h | 35 + source3/nsswitch/winbind_nss_solaris.c | 2 - source3/nsswitch/winbind_nss_solaris.h | 61 ++ 17 files changed, 1745 insertions(+), 1633 deletions(-) delete mode 100644 source3/nsswitch/hp_nss_common.h delete mode 100644 source3/nsswitch/hp_nss_dbdefs.h delete mode 100644 source3/nsswitch/nss.h delete mode 100644 source3/nsswitch/winbind_nss.c create mode 100644 source3/nsswitch/winbind_nss.h create mode 100644 source3/nsswitch/winbind_nss_hpux.h create mode 100644 source3/nsswitch/winbind_nss_irix.c create mode 100644 source3/nsswitch/winbind_nss_irix.h create mode 100644 source3/nsswitch/winbind_nss_linux.c create mode 100644 source3/nsswitch/winbind_nss_linux.h create mode 100644 source3/nsswitch/winbind_nss_solaris.h (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index f712d99693..75a8db30c2 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -589,7 +589,7 @@ WINBINDD_OBJ = \ WBINFO_OBJ = nsswitch/wbinfo.o libsmb/smbencrypt.o libsmb/smbdes.o $(POPT_LIB_OBJ) -WINBIND_NSS_OBJ = nsswitch/winbind_nss.o nsswitch/wb_common.o @WINBIND_NSS_EXTRA_OBJS@ +WINBIND_NSS_OBJ = nsswitch/wb_common.o @WINBIND_NSS_EXTRA_OBJS@ WINBIND_NSS_PICOBJS = $(WINBIND_NSS_OBJ:.o=.po) @@ -1328,4 +1328,3 @@ check: check-programs # These are called by the test suite check-programs: bin/t_strcmp - diff --git a/source3/configure.in b/source3/configure.in index e16836dd83..0e5733ca5c 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -3166,12 +3166,18 @@ AC_MSG_CHECKING(whether to build winbind) # Initially, the value of $host_os decides whether winbind is supported case "$host_os" in - *linux*|*irix*) + *linux*) HAVE_WINBIND=yes + WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_linux.o" + ;; + *irix*) + HAVE_WINBIND=yes + WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_irix.o" ;; *solaris*) HAVE_WINBIND=yes - WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_solaris.o" + WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_solaris.o \ + nsswitch/winbind_nss_linux.o" WINBIND_NSS_EXTRA_LIBS="-lsocket" ;; *hpux11*) diff --git a/source3/include/includes.h b/source3/include/includes.h index e8e0751cab..3656a8454e 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -847,7 +847,7 @@ struct functable { #define UNI_XDIGIT 0x8 #define UNI_SPACE 0x10 -#include "nsswitch/nss.h" +#include "nsswitch/winbind_nss.h" /* forward declaration from printing.h to get around header file dependencies */ diff --git a/source3/nsswitch/hp_nss_common.h b/source3/nsswitch/hp_nss_common.h deleted file mode 100644 index 5bd5374182..0000000000 --- a/source3/nsswitch/hp_nss_common.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef _HP_NSS_COMMON_H -#define _HP_NSS_COMMON_H - -/* - Unix SMB/CIFS implementation. - - Donated by HP to enable Winbindd to build on HPUX 11.x. - Copyright (C) Jeremy Allison 2002. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ - -#ifdef HAVE_SYNCH_H -#include -#endif -#ifdef HAVE_PTHREAD_H -#include -#endif - -typedef enum { - NSS_SUCCESS, - NSS_NOTFOUND, - NSS_UNAVAIL, - NSS_TRYAGAIN -} nss_status_t; - -struct nss_backend; - -typedef nss_status_t (*nss_backend_op_t)(struct nss_backend *, void *args); - -struct nss_backend { - nss_backend_op_t *ops; - int n_ops; -}; -typedef struct nss_backend nss_backend_t; -typedef int nss_dbop_t; - -#endif /* _HP_NSS_COMMON_H */ diff --git a/source3/nsswitch/hp_nss_dbdefs.h b/source3/nsswitch/hp_nss_dbdefs.h deleted file mode 100644 index bd24772e33..0000000000 --- a/source3/nsswitch/hp_nss_dbdefs.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef _HP_NSS_DBDEFS_H -#define _HP_NSS_DBDEFS_H - -/* - Unix SMB/CIFS implementation. - - Donated by HP to enable Winbindd to build on HPUX 11.x. - Copyright (C) Jeremy Allison 2002. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ - -#include -#include -#include - -#ifndef NSS_INCLUDE_UNSAFE -#define NSS_INCLUDE_UNSAFE 1 /* Build old, MT-unsafe interfaces, */ -#endif /* NSS_INCLUDE_UNSAFE */ - -enum nss_netgr_argn { - NSS_NETGR_MACHINE, - NSS_NETGR_USER, - NSS_NETGR_DOMAIN, - NSS_NETGR_N -}; - -enum nss_netgr_status { - NSS_NETGR_FOUND, - NSS_NETGR_NO, - NSS_NETGR_NOMEM -}; - -typedef unsigned nss_innetgr_argc; -typedef char **nss_innetgr_argv; - -struct nss_innetgr_1arg { - nss_innetgr_argc argc; - nss_innetgr_argv argv; -}; - -typedef struct { - void *result; /* "result" parameter to getXbyY_r() */ - char *buffer; /* "buffer" " " */ - int buflen; /* "buflen" " " */ -} nss_XbyY_buf_t; - -extern nss_XbyY_buf_t *_nss_XbyY_buf_alloc(int struct_size, int buffer_size); -extern void _nss_XbyY_buf_free(nss_XbyY_buf_t *); - -union nss_XbyY_key { - uid_t uid; - gid_t gid; - const char *name; - int number; - struct { - long net; - int type; - } netaddr; - struct { - const char *addr; - int len; - int type; - } hostaddr; - struct { - union { - const char *name; - int port; - } serv; - const char *proto; - } serv; - void *ether; -}; - -typedef struct nss_XbyY_args { - nss_XbyY_buf_t buf; - int stayopen; - /* - * Support for setXXXent(stayopen) - * Used only in hosts, protocols, - * networks, rpc, and services. - */ - int (*str2ent)(const char *instr, int instr_len, void *ent, char *buffer, int buflen); - union nss_XbyY_key key; - - void *returnval; - int erange; - int h_errno; - nss_status_t status; -} nss_XbyY_args_t; - -#endif /* _NSS_DBDEFS_H */ diff --git a/source3/nsswitch/nss.h b/source3/nsswitch/nss.h deleted file mode 100644 index d83a5e237e..0000000000 --- a/source3/nsswitch/nss.h +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef _NSSWITCH_NSS_H -#define _NSSWITCH_NSS_H -/* - Unix SMB/CIFS implementation. - - a common place to work out how to define NSS_STATUS on various - platforms - - Copyright (C) Tim Potter 2000 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ - -#ifdef HAVE_NSS_COMMON_H - -/* Sun Solaris */ - -#include -#include -#include - -typedef nss_status_t NSS_STATUS; - -#define NSS_STATUS_SUCCESS NSS_SUCCESS -#define NSS_STATUS_NOTFOUND NSS_NOTFOUND -#define NSS_STATUS_UNAVAIL NSS_UNAVAIL -#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN - -#elif HAVE_NSS_H - -/* GNU */ - -#include - -typedef enum nss_status NSS_STATUS; - -#elif HAVE_NS_API_H - -/* SGI IRIX */ - -/* following required to prevent warnings of double definition - * of datum from ns_api.h -*/ -#ifdef DATUM -#define _DATUM_DEFINED -#endif - -#include - -typedef enum -{ - NSS_STATUS_SUCCESS=NS_SUCCESS, - NSS_STATUS_NOTFOUND=NS_NOTFOUND, - NSS_STATUS_UNAVAIL=NS_UNAVAIL, - NSS_STATUS_TRYAGAIN=NS_TRYAGAIN -} NSS_STATUS; - -#define NSD_MEM_STATIC 0 -#define NSD_MEM_VOLATILE 1 -#define NSD_MEM_DYNAMIC 2 - -#elif defined(HPUX) && defined(HAVE_NSSWITCH_H) -/* HP-UX 11 */ - -#include "nsswitch/hp_nss_common.h" -#include "nsswitch/hp_nss_dbdefs.h" -#include - -#ifndef _HAVE_TYPEDEF_NSS_STATUS -#define _HAVE_TYPEDEF_NSS_STATUS -typedef nss_status_t NSS_STATUS; - -#define NSS_STATUS_SUCCESS NSS_SUCCESS -#define NSS_STATUS_NOTFOUND NSS_NOTFOUND -#define NSS_STATUS_UNAVAIL NSS_UNAVAIL -#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN -#endif /* HPUX */ - -#else /* Nothing's defined. Neither gnu nor sun nor hp */ - -typedef enum -{ - NSS_STATUS_SUCCESS=0, - NSS_STATUS_NOTFOUND=1, - NSS_STATUS_UNAVAIL=2, - NSS_STATUS_TRYAGAIN=3 -} NSS_STATUS; - -#endif - -#endif /* _NSSWITCH_NSS_H */ diff --git a/source3/nsswitch/wb_client.c b/source3/nsswitch/wb_client.c index 62c9686960..996d15180d 100644 --- a/source3/nsswitch/wb_client.c +++ b/source3/nsswitch/wb_client.c @@ -23,7 +23,7 @@ */ #include "includes.h" -#include "nsswitch/nss.h" +#include "nsswitch/winbind_nss.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND diff --git a/source3/nsswitch/winbind_nss.c b/source3/nsswitch/winbind_nss.c deleted file mode 100644 index 0b4c0ce1d0..0000000000 --- a/source3/nsswitch/winbind_nss.c +++ /dev/null @@ -1,1341 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Windows NT Domain nsswitch module - - Copyright (C) Tim Potter 2000 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ - -#include "winbind_client.h" - -#ifdef HAVE_NS_API_H -#undef VOLATILE - -#include -#endif - -#define MAX_GETPWENT_USERS 250 -#define MAX_GETGRENT_USERS 250 - -/* Prototypes from wb_common.c */ - -extern int winbindd_fd; - - -#ifdef HAVE_NS_API_H -/* IRIX version */ - -static int send_next_request(nsd_file_t *, struct winbindd_request *); -static int do_list(int state, nsd_file_t *rq); - -static nsd_file_t *current_rq = NULL; -static int current_winbind_xid = 0; -static int next_winbind_xid = 0; - -typedef struct winbind_xid { - int xid; - nsd_file_t *rq; - struct winbindd_request *request; - struct winbind_xid *next; -} winbind_xid_t; - -static winbind_xid_t *winbind_xids = (winbind_xid_t *)0; - -static int -winbind_xid_new(int xid, nsd_file_t *rq, struct winbindd_request *request) -{ - winbind_xid_t *new; - - nsd_logprintf(NSD_LOG_LOW, - "entering winbind_xid_new xid = %d rq = 0x%x, request = 0x%x\n", - xid, rq, request); - new = (winbind_xid_t *)nsd_calloc(1,sizeof(winbind_xid_t)); - if (!new) { - nsd_logprintf(NSD_LOG_RESOURCE,"winbind_xid_new: failed malloc\n"); - return NSD_ERROR; - } - - new->xid = xid; - new->rq = rq; - new->request = request; - new->next = winbind_xids; - winbind_xids = new; - - return NSD_CONTINUE; -} - -/* -** This routine will look down the xid list and return the request -** associated with an xid. We remove the record if it is found. -*/ -nsd_file_t * -winbind_xid_lookup(int xid, struct winbindd_request **requestp) -{ - winbind_xid_t **last, *dx; - nsd_file_t *result=0; - - for (last = &winbind_xids, dx = winbind_xids; dx && (dx->xid != xid); - last = &dx->next, dx = dx->next); - if (dx) { - *last = dx->next; - result = dx->rq; - *requestp = dx->request; - SAFE_FREE(dx); - } - nsd_logprintf(NSD_LOG_LOW, - "entering winbind_xid_lookup xid = %d rq = 0x%x, request = 0x%x\n", - xid, result, dx->request); - - return result; -} - -static int -winbind_startnext_timeout(nsd_file_t **rqp, nsd_times_t *to) -{ - nsd_file_t *rq; - struct winbindd_request *request; - - nsd_logprintf(NSD_LOG_MIN, "timeout (winbind startnext)\n"); - rq = to->t_file; - *rqp = rq; - nsd_timeout_remove(rq); - request = to->t_clientdata; - return(send_next_request(rq, request)); -} - -static void -dequeue_request() -{ - nsd_file_t *rq; - struct winbindd_request *request; - - /* - * Check for queued requests - */ - if (winbind_xids) { - nsd_logprintf(NSD_LOG_MIN, "timeout (winbind) unqueue xid %d\n", - current_winbind_xid); - rq = winbind_xid_lookup(current_winbind_xid++, &request); - /* cause a timeout on the queued request so we can send it */ - nsd_timeout_new(rq,1,winbind_startnext_timeout,request); - } -} - -static int -do_request(nsd_file_t *rq, struct winbindd_request *request) -{ - if (winbind_xids == NULL) { - /* - * No outstanding requests. - * Send off the request to winbindd - */ - nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) sending request\n"); - return(send_next_request(rq, request)); - } else { - /* - * Just queue it up for now - previous callout or timout - * will start it up - */ - nsd_logprintf(NSD_LOG_MIN, - "lookup (winbind): queue request xid = %d\n", - next_winbind_xid); - return(winbind_xid_new(next_winbind_xid++, rq, request)); - } -} - -static int -winbind_callback(nsd_file_t **rqp, int fd) -{ - struct winbindd_response response; - struct winbindd_pw *pw = &response.data.pw; - struct winbindd_gr *gr = &response.data.gr; - nsd_file_t *rq; - NSS_STATUS status; - fstring result; - char *members; - int i, maxlen; - - dequeue_request(); - - nsd_logprintf(NSD_LOG_MIN, "entering callback (winbind)\n"); - - rq = current_rq; - *rqp = rq; - - nsd_timeout_remove(rq); - nsd_callback_remove(fd); - - ZERO_STRUCT(response); - status = winbindd_get_response(&response); - - if (status != NSS_STATUS_SUCCESS) { - /* free any extra data area in response structure */ - free_response(&response); - nsd_logprintf(NSD_LOG_MIN, - "callback (winbind) returning not found, status = %d\n", - status); - rq->f_status = NS_NOTFOUND; - return NSD_NEXT; - } - - maxlen = sizeof(result) - 1; - - switch ((int)rq->f_cmd_data) { - case WINBINDD_WINS_BYNAME: - case WINBINDD_WINS_BYIP: - snprintf(result,maxlen,"%s\n",response.data.winsresp); - break; - case WINBINDD_GETPWUID: - case WINBINDD_GETPWNAM: - snprintf(result,maxlen,"%s:%s:%d:%d:%s:%s:%s\n", - pw->pw_name, - pw->pw_passwd, - pw->pw_uid, - pw->pw_gid, - pw->pw_gecos, - pw->pw_dir, - pw->pw_shell); - break; - case WINBINDD_GETGRNAM: - case WINBINDD_GETGRGID: - if (gr->num_gr_mem && response.extra_data) - members = response.extra_data; - else - members = ""; - snprintf(result,maxlen,"%s:%s:%d:%s\n", - gr->gr_name, gr->gr_passwd, gr->gr_gid, members); - break; - case WINBINDD_SETGRENT: - case WINBINDD_SETPWENT: - nsd_logprintf(NSD_LOG_MIN, "callback (winbind) - SETPWENT/SETGRENT\n"); - free_response(&response); - return(do_list(1,rq)); - case WINBINDD_GETGRENT: - case WINBINDD_GETGRLST: - nsd_logprintf(NSD_LOG_MIN, - "callback (winbind) - %d GETGRENT responses\n", - response.data.num_entries); - if (response.data.num_entries) { - gr = (struct winbindd_gr *)response.extra_data; - if (! gr ) { - nsd_logprintf(NSD_LOG_MIN, " no extra_data\n"); - free_response(&response); - return NSD_ERROR; - } - members = (char *)response.extra_data + - (response.data.num_entries * sizeof(struct winbindd_gr)); - for (i = 0; i < response.data.num_entries; i++) { - snprintf(result,maxlen,"%s:%s:%d:%s\n", - gr->gr_name, gr->gr_passwd, gr->gr_gid, - &members[gr->gr_mem_ofs]); - nsd_logprintf(NSD_LOG_MIN, " GETGRENT %s\n",result); - nsd_append_element(rq,NS_SUCCESS,result,strlen(result)); - gr++; - } - } - i = response.data.num_entries; - free_response(&response); - if (i < MAX_GETPWENT_USERS) - return(do_list(2,rq)); - else - return(do_list(1,rq)); - case WINBINDD_GETPWENT: - nsd_logprintf(NSD_LOG_MIN, - "callback (winbind) - %d GETPWENT responses\n", - response.data.num_entries); - if (response.data.num_entries) { - pw = (struct winbindd_pw *)response.extra_data; - if (! pw ) { - nsd_logprintf(NSD_LOG_MIN, " no extra_data\n"); - free_response(&response); - return NSD_ERROR; - } - for (i = 0; i < response.data.num_entries; i++) { - snprintf(result,maxlen,"%s:%s:%d:%d:%s:%s:%s", - pw->pw_name, - pw->pw_passwd, - pw->pw_uid, - pw->pw_gid, - pw->pw_gecos, - pw->pw_dir, - pw->pw_shell); - nsd_logprintf(NSD_LOG_MIN, " GETPWENT %s\n",result); - nsd_append_element(rq,NS_SUCCESS,result,strlen(result)); - pw++; - } - } - i = response.data.num_entries; - free_response(&response); - if (i < MAX_GETPWENT_USERS) - return(do_list(2,rq)); - else - return(do_list(1,rq)); - case WINBINDD_ENDGRENT: - case WINBINDD_ENDPWENT: - nsd_logprintf(NSD_LOG_MIN, "callback (winbind) - ENDPWENT/ENDGRENT\n"); - nsd_append_element(rq,NS_SUCCESS,"\n",1); - free_response(&response); - return NSD_NEXT; - default: - free_response(&response); - nsd_logprintf(NSD_LOG_MIN, "callback (winbind) - no valid command\n"); - return NSD_NEXT; - } - nsd_logprintf(NSD_LOG_MIN, "callback (winbind) %s\n", result); - /* free any extra data area in response structure */ - free_response(&response); - nsd_set_result(rq,NS_SUCCESS,result,strlen(result),VOLATILE); - return NSD_OK; -} - -static int -winbind_timeout(nsd_file_t **rqp, nsd_times_t *to) -{ - nsd_file_t *rq; - - dequeue_request(); - - nsd_logprintf(NSD_LOG_MIN, "timeout (winbind)\n"); - - rq = to->t_file; - *rqp = rq; - - /* Remove the callback and timeout */ - nsd_callback_remove(winbindd_fd); - nsd_timeout_remove(rq); - - rq->f_status = NS_NOTFOUND; - return NSD_NEXT; -} - -static int -send_next_request(nsd_file_t *rq, struct winbindd_request *request) -{ - NSS_STATUS status; - long timeout; - - timeout = 1000; - - nsd_logprintf(NSD_LOG_MIN, "send_next_request (winbind) %d to = %d\n", - rq->f_cmd_data, timeout); - status = winbindd_send_request((int)rq->f_cmd_data,request); - SAFE_FREE(request); - - if (status != NSS_STATUS_SUCCESS) { - nsd_logprintf(NSD_LOG_MIN, - "send_next_request (winbind) error status = %d\n",status); - rq->f_status = status; - return NSD_NEXT; - } - - current_rq = rq; - - /* - * Set up callback and timeouts - */ - nsd_logprintf(NSD_LOG_MIN, "send_next_request (winbind) fd = %d\n",winbindd_fd); - nsd_callback_new(winbindd_fd,winbind_callback,NSD_READ); - nsd_timeout_new(rq,timeout,winbind_timeout,(void *)0); - return NSD_CONTINUE; -} - -int init(void) -{ - nsd_logprintf(NSD_LOG_MIN, "entering init (winbind)\n"); - return(NSD_OK); -} - -int lookup(nsd_file_t *rq) -{ - char *map; - char *key; - struct winbindd_request *request; - - nsd_logprintf(NSD_LOG_MIN, "entering lookup (winbind)\n"); - if (! rq) - return NSD_ERROR; - - map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0); - key = nsd_attr_fetch_string(rq->f_attrs, "key", (char*)0); - if (! map || ! key) { - nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) table or key not defined\n"); - rq->f_status = NS_BADREQ; - return NSD_ERROR; - } - - nsd_logprintf(NSD_LOG_MIN, "lookup (winbind %s)\n",map); - - request = (struct winbindd_request *)nsd_calloc(1,sizeof(struct winbindd_request)); - if (! request) { - nsd_logprintf(NSD_LOG_RESOURCE, - "lookup (winbind): failed malloc\n"); - return NSD_ERROR; - } - - if (strcasecmp(map,"passwd.byuid") == 0) { - request->data.uid = atoi(key); - rq->f_cmd_data = (void *)WINBINDD_GETPWUID; - } else if (strcasecmp(map,"passwd.byname") == 0) { - strncpy(request->data.username, key, - sizeof(request->data.username) - 1); - request->data.username[sizeof(request->data.username) - 1] = '\0'; - rq->f_cmd_data = (void *)WINBINDD_GETPWNAM; - } else if (strcasecmp(map,"group.byname") == 0) { - strncpy(request->data.groupname, key, - sizeof(request->data.groupname) - 1); - request->data.groupname[sizeof(request->data.groupname) - 1] = '\0'; - rq->f_cmd_data = (void *)WINBINDD_GETGRNAM; - } else if (strcasecmp(map,"group.bygid") == 0) { - request->data.gid = atoi(key); - rq->f_cmd_data = (void *)WINBINDD_GETGRGID; - } else if (strcasecmp(map,"hosts.byname") == 0) { - strncpy(request->data.winsreq, key, sizeof(request->data.winsreq) - 1); - request->data.winsreq[sizeof(request->data.winsreq) - 1] = '\0'; - rq->f_cmd_data = (void *)WINBINDD_WINS_BYNAME; - } else if (strcasecmp(map,"hosts.byaddr") == 0) { - strncpy(request->data.winsreq, key, sizeof(request->data.winsreq) - 1); - request->data.winsreq[sizeof(request->data.winsreq) - 1] = '\0'; - rq->f_cmd_data = (void *)WINBINDD_WINS_BYIP; - } else { - /* - * Don't understand this map - just return not found - */ - nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) unknown table\n"); - SAFE_FREE(request); - rq->f_status = NS_NOTFOUND; - return NSD_NEXT; - } - - return(do_request(rq, request)); -} - -int list(nsd_file_t *rq) -{ - char *map; - - nsd_logprintf(NSD_LOG_MIN, "entering list (winbind)\n"); - if (! rq) - return NSD_ERROR; - - map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0); - if (! map ) { - nsd_logprintf(NSD_LOG_MIN, "list (winbind) table not defined\n"); - rq->f_status = NS_BADREQ; - return NSD_ERROR; - } - - nsd_logprintf(NSD_LOG_MIN, "list (winbind %s)\n",map); - - return (do_list(0,rq)); -} - -static int -do_list(int state, nsd_file_t *rq) -{ - char *map; - struct winbindd_request *request; - - nsd_logprintf(NSD_LOG_MIN, "entering do_list (winbind) state = %d\n",state); - - map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0); - request = (struct winbindd_request *)nsd_calloc(1,sizeof(struct winbindd_request)); - if (! request) { - nsd_logprintf(NSD_LOG_RESOURCE, - "do_list (winbind): failed malloc\n"); - return NSD_ERROR; - } - - if (strcasecmp(map,"passwd.byname") == 0) { - switch (state) { - case 0: - rq->f_cmd_data = (void *)WINBINDD_SETPWENT; - break; - case 1: - request->data.num_entries = MAX_GETPWENT_USERS; - rq->f_cmd_data = (void *)WINBINDD_GETPWENT; - break; - case 2: - rq->f_cmd_data = (void *)WINBINDD_ENDPWENT; - break; - default: - nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown state\n"); - SAFE_FREE(request); - rq->f_status = NS_NOTFOUND; - return NSD_NEXT; - } - } else if (strcasecmp(map,"group.byname") == 0) { - switch (state) { - case 0: - rq->f_cmd_data = (void *)WINBINDD_SETGRENT; - break; - case 1: - request->data.num_entries = MAX_GETGRENT_USERS; - rq->f_cmd_data = (void *)WINBINDD_GETGRENT; - break; - case 2: - rq->f_cmd_data = (void *)WINBINDD_ENDGRENT; - break; - default: - nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown state\n"); - SAFE_FREE(request); - rq->f_status = NS_NOTFOUND; - return NSD_NEXT; - } - } else { - /* - * Don't understand this map - just return not found - */ - nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown table\n"); - SAFE_FREE(request); - rq->f_status = NS_NOTFOUND; - return NSD_NEXT; - } - - return(do_request(rq, request)); -} - -#else - -/* Allocate some space from the nss static buffer. The buffer and buflen - are the pointers passed in by the C library to the _nss_ntdom_* - functions. */ - -static char *get_static(char **buffer, int *buflen, int len) -{ - char *result; - - /* Error check. We return false if things aren't set up right, or - there isn't enough buffer space left. */ - - if ((buffer == NULL) || (buflen == NULL) || (*buflen < len)) { - return NULL; - } - - /* Return an index into the static buffer */ - - result = *buffer; - *buffer += len; - *buflen -= len; - - return result; -} - -/* I've copied the strtok() replacement function next_token() from - lib/util_str.c as I really don't want to have to link in any other - objects if I can possibly avoid it. */ - -BOOL next_token(char **ptr,char *buff,char *sep, size_t bufsize) -{ - char *s; - BOOL quoted; - size_t len=1; - - if (!ptr) return(False); - - s = *ptr; - - /* default to simple separators */ - if (!sep) sep = " \t\n\r"; - - /* find the first non sep char */ - while (*s && strchr(sep,*s)) s++; - - /* nothing left? */ - if (! *s) return(False); - - /* copy over the token */ - for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++) { - if (*s == '\"') { - quoted = !quoted; - } else { - len++; - *buff++ = *s; - } - } - - *ptr = (*s) ? s+1 : s; - *buff = 0; - - return(True); -} - - -/* Fill a pwent structure from a winbindd_response structure. We use - the static data passed to us by libc to put strings and stuff in. - Return NSS_STATUS_TRYAGAIN if we run out of memory. */ - -static NSS_STATUS fill_pwent(struct passwd *result, - struct winbindd_pw *pw, - char **buffer, size_t *buflen) -{ - /* User name */ - - if ((result->pw_name = - get_static(buffer, buflen, strlen(pw->pw_name) + 1)) == NULL) { - - /* Out of memory */ - - return NSS_STATUS_TRYAGAIN; - } - - strcpy(result->pw_name, pw->pw_name); - - /* Password */ - - if ((result->pw_passwd = - get_static(buffer, buflen, strlen(pw->pw_passwd) + 1)) == NULL) { - - /* Out of memory */ - - return NSS_STATUS_TRYAGAIN; - } - - strcpy(result->pw_passwd, pw->pw_passwd); - - /* [ug]id */ - - result->pw_uid = pw->pw_uid; - result->pw_gid = pw->pw_gid; - - /* GECOS */ - - if ((result->pw_gecos = - get_static(buffer, buflen, strlen(pw->pw_gecos) + 1)) == NULL) { - - /* Out of memory */ - - return NSS_STATUS_TRYAGAIN; - } - - strcpy(result->pw_gecos, pw->pw_gecos); - - /* Home directory */ - - if ((result->pw_dir = - get_static(buffer, buflen, strlen(pw->pw_dir) + 1)) == NULL) { - - /* Out of memory */ - - return NSS_STATUS_TRYAGAIN; - } - - strcpy(result->pw_dir, pw->pw_dir); - - /* Logon shell */ - - if ((result->pw_shell = - get_static(buffer, buflen, strlen(pw->pw_shell) + 1)) == NULL) { - - /* Out of memory */ - - return NSS_STATUS_TRYAGAIN; - } - - strcpy(result->pw_shell, pw->pw_shell); - - /* The struct passwd for Solaris has some extra fields which must - be initialised or nscd crashes. */ - -#if HAVE_PASSWD_PW_COMMENT - result->pw_comment = ""; -#endif - -#if HAVE_PASSWD_PW_AGE - result->pw_age = ""; -#endif - - return NSS_STATUS_SUCCESS; -} - -/* Fill a grent structure from a winbindd_response structure. We use - the static data passed to us by libc to put strings and stuff in. - Return NSS_STATUS_TRYAGAIN if we run out of memory. */ - -static NSS_STATUS fill_grent(struct group *result, struct winbindd_gr *gr, - char *gr_mem, char **buffer, size_t *buflen) -{ - fstring name; - int i; - char *tst; - - /* Group name */ - - if ((result->gr_name = - get_static(buffer, buflen, strlen(gr->gr_name) + 1)) == NULL) { - - /* Out of memory */ - - return NSS_STATUS_TRYAGAIN; - } - - strcpy(result->gr_name, gr->gr_name); - - /* Password */ - - if ((result->gr_passwd = - get_static(buffer, buflen, strlen(gr->gr_passwd) + 1)) == NULL) { - - /* Out of memory */ - - return NSS_STATUS_TRYAGAIN; - } - - strcpy(result->gr_passwd, gr->gr_passwd); - - /* gid */ - - result->gr_gid = gr->gr_gid; - - /* Group membership */ - - if ((gr->num_gr_mem < 0) || !gr_mem) { - gr->num_gr_mem = 0; - } - - /* this next value is a pointer to a pointer so let's align it */ - - /* Calculate number of extra bytes needed to align on pointer size boundry */ - if ((i = (unsigned long)(*buffer) % sizeof(char*)) != 0) - i = sizeof(char*) - i; - - if ((tst = get_static(buffer, buflen, ((gr->num_gr_mem + 1) * - sizeof(char *)+i))) == NULL) { - - /* Out of memory */ - - return NSS_STATUS_TRYAGAIN; - } - result->gr_mem = (char **)(tst + i); - - if (gr->num_gr_mem == 0) { - - /* Group is empty */ - - *(result->gr_mem) = NULL; - return NSS_STATUS_SUCCESS; - } - - /* Start looking at extra data */ - - i = 0; - - while(next_token((char **)&gr_mem, name, ",", sizeof(fstring))) { - - /* Allocate space for member */ - - if (((result->gr_mem)[i] = - get_static(buffer, buflen, strlen(name) + 1)) == NULL) { - - /* Out of memory */ - - return NSS_STATUS_TRYAGAIN; - } - - strcpy((result->gr_mem)[i], name); - i++; - } - - /* Terminate list */ - - (result->gr_mem)[i] = NULL; - - return NSS_STATUS_SUCCESS; -} - -/* - * NSS user functions - */ - -static struct winbindd_response getpwent_response; - -static int ndx_pw_cache; /* Current index into pwd cache */ -static int num_pw_cache; /* Current size of pwd cache */ - -/* Rewind "file pointer" to start of ntdom password database */ - -NSS_STATUS -_nss_winbind_setpwent(void) -{ -#ifdef DEBUG_NSS - fprintf(stderr, "[%5d]: setpwent\n", getpid()); -#endif - - if (num_pw_cache > 0) { - ndx_pw_cache = num_pw_cache = 0; - free_response(&getpwent_response); - } - - return winbindd_request(WINBINDD_SETPWENT, NULL, NULL); -} - -/* Close ntdom password database "file pointer" */ - -NSS_STATUS -_nss_winbind_endpwent(void) -{ -#ifdef DEBUG_NSS - fprintf(stderr, "[%5d]: endpwent\n", getpid()); -#endif - - if (num_pw_cache > 0) { - ndx_pw_cache = num_pw_cache = 0; - free_response(&getpwent_response); - } - - return winbindd_request(WINBINDD_ENDPWENT, NULL, NULL); -} - -/* Fetch the next password entry from ntdom password database */ - -NSS_STATUS -_nss_winbind_getpwent_r(struct passwd *result, char *buffer, - size_t buflen, int *errnop) -{ - NSS_STATUS ret; - struct winbindd_request request; - static int called_again; - -#ifdef DEBUG_NSS - fprintf(stderr, "[%5d]: getpwent\n", getpid()); -#endif - - /* Return an entry from the cache if we have one, or if we are - called again because we exceeded our static buffer. */ - - if ((ndx_pw_cache < num_pw_cache) || called_again) { - goto return_result; - } - - /* Else call winbindd to get a bunch of entries */ - - if (num_pw_cache > 0) { - free_response(&getpwent_response); - } - - ZERO_STRUCT(request); - ZERO_STRUCT(getpwent_response); - - request.data.num_entries = MAX_GETPWENT_USERS; - - ret = winbindd_request(WINBINDD_GETPWENT, &request, - &getpwent_response); - - if (ret == NSS_STATUS_SUCCESS) { - struct winbindd_pw *pw_cache; - - /* Fill cache */ - - ndx_pw_cache = 0; - num_pw_cache = getpwent_response.data.num_entries; - - /* Return a result */ - - return_result: - - pw_cache = getpwent_response.extra_data; - - /* Check data is valid */ - - if (pw_cache == NULL) { - return NSS_STATUS_NOTFOUND; - } - - ret = fill_pwent(result, &pw_cache[ndx_pw_cache], - &buffer, &buflen); - - /* Out of memory - try again */ - - if (ret == NSS_STATUS_TRYAGAIN) { - called_again = True; - *errnop = errno = ERANGE; - return ret; - } - - *errnop = errno = 0; - called_again = False; - ndx_pw_cache++; - - /* If we've finished with this lot of results free cache */ - - if (ndx_pw_cache == num_pw_cache) { - ndx_pw_cache = num_pw_cache = 0; - free_response(&getpwent_response); - } - } - - return ret; -} - -/* Return passwd struct from uid */ - -NSS_STATUS -_nss_winbind_getpwuid_r(uid_t uid, struct passwd *result, char *buffer, - size_t buflen, int *errnop) -{ - NSS_STATUS ret; - static struct winbindd_response response; - struct winbindd_request request; - static int keep_response=0; - - /* If our static buffer needs to be expanded we are called again */ - if (!keep_response) { - - /* Call for the first time */ - - ZERO_STRUCT(response); - ZERO_STRUCT(request); - - request.data.uid = uid; - - ret = winbindd_request(WINBINDD_GETPWUID, &request, &response); - - if (ret == NSS_STATUS_SUCCESS) { - ret = fill_pwent(result, &response.data.pw, - &buffer, &buflen); - - if (ret == NSS_STATUS_TRYAGAIN) { - keep_response = True; - *errnop = errno = ERANGE; - return ret; - } - } - - } else { - - /* We've been called again */ - - ret = fill_pwent(result, &response.data.pw, &buffer, &buflen); - - if (ret == NSS_STATUS_TRYAGAIN) { - keep_response = True; - *errnop = errno = ERANGE; - return ret; - } - - keep_response = False; - *errnop = errno = 0; - } - - free_response(&response); - return ret; -} - -/* Return passwd struct from username */ - -NSS_STATUS -_nss_winbind_getpwnam_r(const char *name, struct passwd *result, char *buffer, - size_t buflen, int *errnop) -{ - NSS_STATUS ret; - static struct winbindd_response response; - struct winbindd_request request; - static int keep_response; - -#ifdef DEBUG_NSS - fprintf(stderr, "[%5d]: getpwnam %s\n", getpid(), name); -#endif - - /* If our static buffer needs to be expanded we are called again */ - - if (!keep_response) { - - /* Call for the first time */ - - ZERO_STRUCT(response); - ZERO_STRUCT(request); - - strncpy(request.data.username, name, - sizeof(request.data.username) - 1); - request.data.username - [sizeof(request.data.username) - 1] = '\0'; - - ret = winbindd_request(WINBINDD_GETPWNAM, &request, &response); - - if (ret == NSS_STATUS_SUCCESS) { - ret = fill_pwent(result, &response.data.pw, &buffer, - &buflen); - - if (ret == NSS_STATUS_TRYAGAIN) { - keep_response = True; - *errnop = errno = ERANGE; - return ret; - } - } - - } else { - - /* We've been called again */ - - ret = fill_pwent(result, &response.data.pw, &buffer, &buflen); - - if (ret == NSS_STATUS_TRYAGAIN) { - keep_response = True; - *errnop = errno = ERANGE; - return ret; - } - - keep_response = False; - *errnop = errno = 0; - } - - free_response(&response); - return ret; -} - -/* - * NSS group functions - */ - -static struct winbindd_response getgrent_response; - -static int ndx_gr_cache; /* Current index into grp cache */ -static int num_gr_cache; /* Current size of grp cache */ - -/* Rewind "file pointer" to start of ntdom group database */ - -NSS_STATUS -_nss_winbind_setgrent(void) -{ -#ifdef DEBUG_NSS - fprintf(stderr, "[%5d]: setgrent\n", getpid()); -#endif - - if (num_gr_cache > 0) { - ndx_gr_cache = num_gr_cache = 0; - free_response(&getgrent_response); - } - - return winbindd_request(WINBINDD_SETGRENT, NULL, NULL); -} - -/* Close "file pointer" for ntdom group database */ - -NSS_STATUS -_nss_winbind_endgrent(void) -{ -#ifdef DEBUG_NSS - fprintf(stderr, "[%5d]: endgrent\n", getpid()); -#endif - - if (num_gr_cache > 0) { - ndx_gr_cache = num_gr_cache = 0; - free_response(&getgrent_response); - } - - return winbindd_request(WINBINDD_ENDGRENT, NULL, NULL); -} - -/* Get next entry from ntdom group database */ - -static NSS_STATUS -winbind_getgrent(enum winbindd_cmd cmd, - struct group *result, - char *buffer, size_t buflen, int *errnop) -{ - NSS_STATUS ret; - static struct winbindd_request request; - static int called_again; - - -#ifdef DEBUG_NSS - fprintf(stderr, "[%5d]: getgrent\n", getpid()); -#endif - - /* Return an entry from the cache if we have one, or if we are - called again because we exceeded our static buffer. */ - - if ((ndx_gr_cache < num_gr_cache) || called_again) { - goto return_result; - } - - /* Else call winbindd to get a bunch of entries */ - - if (num_gr_cache > 0) { - free_response(&getgrent_response); - } - - ZERO_STRUCT(request); - ZERO_STRUCT(getgrent_response); - - request.data.num_entries = MAX_GETGRENT_USERS; - - ret = winbindd_request(cmd, &request, - &getgrent_response); - - if (ret == NSS_STATUS_SUCCESS) { - struct winbindd_gr *gr_cache; - int mem_ofs; - - /* Fill cache */ - - ndx_gr_cache = 0; - num_gr_cache = getgrent_response.data.num_entries; - - /* Return a result */ - - return_result: - - gr_cache = getgrent_response.extra_data; - - /* Check data is valid */ - - if (gr_cache == NULL) { - return NSS_STATUS_NOTFOUND; - } - - /* Fill group membership. The offset into the extra data - for the group membership is the reported offset plus the - size of all the winbindd_gr records returned. */ - - mem_ofs = gr_cache[ndx_gr_cache].gr_mem_ofs + - num_gr_cache * sizeof(struct winbindd_gr); - - ret = fill_grent(result, &gr_cache[ndx_gr_cache], - ((char *)getgrent_response.extra_data)+mem_ofs, - &buffer, &buflen); - - /* Out of memory - try again */ - - if (ret == NSS_STATUS_TRYAGAIN) { - called_again = True; - *errnop = errno = ERANGE; - return ret; - } - - *errnop = 0; - called_again = False; - ndx_gr_cache++; - - /* If we've finished with this lot of results free cache */ - - if (ndx_gr_cache == num_gr_cache) { - ndx_gr_cache = num_gr_cache = 0; - free_response(&getgrent_response); - } - } - - return ret; -} - - -NSS_STATUS -_nss_winbind_getgrent_r(struct group *result, - char *buffer, size_t buflen, int *errnop) -{ - return winbind_getgrent(WINBINDD_GETGRENT, result, buffer, buflen, errnop); -} - -NSS_STATUS -_nss_winbind_getgrlst_r(struct group *result, - char *buffer, size_t buflen, int *errnop) -{ - return winbind_getgrent(WINBINDD_GETGRLST, result, buffer, buflen, errnop); -} - -/* Return group struct from group name */ - -NSS_STATUS -_nss_winbind_getgrnam_r(const char *name, - struct group *result, char *buffer, - size_t buflen, int *errnop) -{ - NSS_STATUS ret; - static struct winbindd_response response; - struct winbindd_request request; - static int keep_response; - -#ifdef DEBUG_NSS - fprintf(stderr, "[%5d]: getgrnam %s\n", getpid(), name); -#endif - - /* If our static buffer needs to be expanded we are called again */ - - if (!keep_response) { - - /* Call for the first time */ - - ZERO_STRUCT(request); - ZERO_STRUCT(response); - - strncpy(request.data.groupname, name, - sizeof(request.data.groupname)); - request.data.groupname - [sizeof(request.data.groupname) - 1] = '\0'; - - ret = winbindd_request(WINBINDD_GETGRNAM, &request, &response); - - if (ret == NSS_STATUS_SUCCESS) { - ret = fill_grent(result, &response.data.gr, - response.extra_data, - &buffer, &buflen); - - if (ret == NSS_STATUS_TRYAGAIN) { - keep_response = True; - *errnop = errno = ERANGE; - return ret; - } - } - - } else { - - /* We've been called again */ - - ret = fill_grent(result, &response.data.gr, - response.extra_data, &buffer, &buflen); - - if (ret == NSS_STATUS_TRYAGAIN) { - keep_response = True; - *errnop = errno = ERANGE; - return ret; - } - - keep_response = False; - *errnop = 0; - } - - free_response(&response); - return ret; -} - -/* Return group struct from gid */ - -NSS_STATUS -_nss_winbind_getgrgid_r(gid_t gid, - struct group *result, char *buffer, - size_t buflen, int *errnop) -{ - NSS_STATUS ret; - static struct winbindd_response response; - struct winbindd_request request; - static int keep_response; - -#ifdef DEBUG_NSS - fprintf(stderr, "[%5d]: getgrgid %d\n", getpid(), gid); -#endif - - /* If our static buffer needs to be expanded we are called again */ - - if (!keep_response) { - - /* Call for the first time */ - - ZERO_STRUCT(request); - ZERO_STRUCT(response); - - request.data.gid = gid; - - ret = winbindd_request(WINBINDD_GETGRGID, &request, &response); - - if (ret == NSS_STATUS_SUCCESS) { - - ret = fill_grent(result, &response.data.gr, - response.extra_data, - &buffer, &buflen); - - if (ret == NSS_STATUS_TRYAGAIN) { - keep_response = True; - *errnop = errno = ERANGE; - return ret; - } - } - - } else { - - /* We've been called again */ - - ret = fill_grent(result, &response.data.gr, - response.extra_data, &buffer, &buflen); - - if (ret == NSS_STATUS_TRYAGAIN) { - keep_response = True; - *errnop = errno = ERANGE; - return ret; - } - - keep_response = False; - *errnop = 0; - } - - free_response(&response); - return ret; -} - -/* Initialise supplementary groups */ - -NSS_STATUS -_nss_winbind_initgroups_dyn(char *user, gid_t group, long int *start, - long int *size, gid_t **groups, long int limit, - int *errnop) -{ - NSS_STATUS ret; - struct winbindd_request request; - struct winbindd_response response; - int i; - -#ifdef DEBUG_NSS - fprintf(stderr, "[%5d]: initgroups %s (%d)\n", getpid(), - user, group); -#endif - - ZERO_STRUCT(request); - ZERO_STRUCT(response); - - strncpy(request.data.username, user, - sizeof(request.data.username) - 1); - - ret = winbindd_request(WINBINDD_GETGROUPS, &request, &response); - - if (ret == NSS_STATUS_SUCCESS) { - int num_gids = response.data.num_entries; - gid_t *gid_list = (gid_t *)response.extra_data; - - /* Copy group list to client */ - - for (i = 0; i < num_gids; i++) { - - /* Skip primary group */ - - if (gid_list[i] == group) continue; - - /* Add to buffer */ - - if (*start == *size && limit <= 0) { - (*groups) = realloc( - (*groups), (2 * (*size) + 1) * sizeof(**groups)); - if (! *groups) goto done; - *size = 2 * (*size) + 1; - } - - if (*start == *size) goto done; - - (*groups)[*start] = gid_list[i]; - *start += 1; - - /* Filled buffer? */ - - if (*start == limit) goto done; - } - } - - /* Back to your regularly scheduled programming */ - - done: - return ret; -} - -#endif diff --git a/source3/nsswitch/winbind_nss.h b/source3/nsswitch/winbind_nss.h new file mode 100644 index 0000000000..5416ae211e --- /dev/null +++ b/source3/nsswitch/winbind_nss.h @@ -0,0 +1,71 @@ +/* + Unix SMB/CIFS implementation. + + A common place to work out how to define NSS_STATUS on various + platforms. + + Copyright (C) Tim Potter 2000 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef _NSSWITCH_NSS_H +#define _NSSWITCH_NSS_H + +#ifdef HAVE_NSS_COMMON_H + +/* + * Sun Solaris + */ + +#include "nsswitch/winbind_nss_solaris.h" + +#elif HAVE_NSS_H + +/* + * Linux (glibc) + */ + +#include +typedef enum nss_status NSS_STATUS; + +#elif HAVE_NS_API_H + +/* + * SGI IRIX + */ + +#include "nsswitch/winbind_nss_irix.h" + +#elif defined(HPUX) && defined(HAVE_NSSWITCH_H) + +/* HP-UX 11 */ + +#include "nsswitch/winbind_nss_hpux.h" + +#else /* Nothing's defined. Neither gnu nor sun nor hp */ + +typedef enum +{ + NSS_STATUS_SUCCESS=0, + NSS_STATUS_NOTFOUND=1, + NSS_STATUS_UNAVAIL=2, + NSS_STATUS_TRYAGAIN=3 +} NSS_STATUS; + +#endif + +#endif /* _NSSWITCH_NSS_H */ diff --git a/source3/nsswitch/winbind_nss_config.h b/source3/nsswitch/winbind_nss_config.h index 2faaa30d1b..77d1dbe26e 100644 --- a/source3/nsswitch/winbind_nss_config.h +++ b/source3/nsswitch/winbind_nss_config.h @@ -76,30 +76,7 @@ #include #include #include -#include "nsswitch/nss.h" - -/* Declarations for functions in winbind_nss.c - needed in winbind_nss_solaris.c (solaris wrapper to nss) */ - -NSS_STATUS _nss_winbind_setpwent(void); -NSS_STATUS _nss_winbind_endpwent(void); -NSS_STATUS _nss_winbind_getpwent_r(struct passwd* result, char* buffer, - size_t buflen, int* errnop); -NSS_STATUS _nss_winbind_getpwuid_r(uid_t, struct passwd*, char* buffer, - size_t buflen, int* errnop); -NSS_STATUS _nss_winbind_getpwnam_r(const char* name, struct passwd* result, - char* buffer, size_t buflen, int* errnop); - -NSS_STATUS _nss_winbind_setgrent(void); -NSS_STATUS _nss_winbind_endgrent(void); -NSS_STATUS _nss_winbind_getgrent_r(struct group* result, char* buffer, - size_t buflen, int* errnop); -NSS_STATUS _nss_winbind_getgrnam_r(const char *name, - struct group *result, char *buffer, - size_t buflen, int *errnop); -NSS_STATUS _nss_winbind_getgrgid_r(gid_t gid, - struct group *result, char *buffer, - size_t buflen, int *errnop); +#include "nsswitch/winbind_nss.h" /* I'm trying really hard not to include anything from smb.h with the result of some silly looking redeclaration of structures. */ diff --git a/source3/nsswitch/winbind_nss_hpux.h b/source3/nsswitch/winbind_nss_hpux.h new file mode 100644 index 0000000000..1f2bade972 --- /dev/null +++ b/source3/nsswitch/winbind_nss_hpux.h @@ -0,0 +1,141 @@ +/* + Unix SMB/CIFS implementation. + + Donated by HP to enable Winbindd to build on HPUX 11.x. + Copyright (C) Jeremy Allison 2002. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef _WINBIND_NSS_HPUX_H +#define _WINBIND_NSS_HPUX_H + +#include + +#ifndef _HAVE_TYPEDEF_NSS_STATUS +#define _HAVE_TYPEDEF_NSS_STATUS +typedef nss_status_t NSS_STATUS; + +#define NSS_STATUS_SUCCESS NSS_SUCCESS +#define NSS_STATUS_NOTFOUND NSS_NOTFOUND +#define NSS_STATUS_UNAVAIL NSS_UNAVAIL +#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN + +#ifdef HAVE_SYNCH_H +#include +#endif +#ifdef HAVE_PTHREAD_H +#include +#endif + +typedef enum { + NSS_SUCCESS, + NSS_NOTFOUND, + NSS_UNAVAIL, + NSS_TRYAGAIN +} nss_status_t; + +struct nss_backend; + +typedef nss_status_t (*nss_backend_op_t)(struct nss_backend *, void *args); + +struct nss_backend { + nss_backend_op_t *ops; + int n_ops; +}; +typedef struct nss_backend nss_backend_t; +typedef int nss_dbop_t; + +#include +#include +#include + +#ifndef NSS_INCLUDE_UNSAFE +#define NSS_INCLUDE_UNSAFE 1 /* Build old, MT-unsafe interfaces, */ +#endif /* NSS_INCLUDE_UNSAFE */ + +enum nss_netgr_argn { + NSS_NETGR_MACHINE, + NSS_NETGR_USER, + NSS_NETGR_DOMAIN, + NSS_NETGR_N +}; + +enum nss_netgr_status { + NSS_NETGR_FOUND, + NSS_NETGR_NO, + NSS_NETGR_NOMEM +}; + +typedef unsigned nss_innetgr_argc; +typedef char **nss_innetgr_argv; + +struct nss_innetgr_1arg { + nss_innetgr_argc argc; + nss_innetgr_argv argv; +}; + +typedef struct { + void *result; /* "result" parameter to getXbyY_r() */ + char *buffer; /* "buffer" " " */ + int buflen; /* "buflen" " " */ +} nss_XbyY_buf_t; + +extern nss_XbyY_buf_t *_nss_XbyY_buf_alloc(int struct_size, int buffer_size); +extern void _nss_XbyY_buf_free(nss_XbyY_buf_t *); + +union nss_XbyY_key { + uid_t uid; + gid_t gid; + const char *name; + int number; + struct { + long net; + int type; + } netaddr; + struct { + const char *addr; + int len; + int type; + } hostaddr; + struct { + union { + const char *name; + int port; + } serv; + const char *proto; + } serv; + void *ether; +}; + +typedef struct nss_XbyY_args { + nss_XbyY_buf_t buf; + int stayopen; + /* + * Support for setXXXent(stayopen) + * Used only in hosts, protocols, + * networks, rpc, and services. + */ + int (*str2ent)(const char *instr, int instr_len, void *ent, char *buffer, int buflen); + union nss_XbyY_key key; + + void *returnval; + int erange; + int h_errno; + nss_status_t status; +} nss_XbyY_args_t; + +#endif /* _WINBIND_NSS_HPUX_H */ diff --git a/source3/nsswitch/winbind_nss_irix.c b/source3/nsswitch/winbind_nss_irix.c new file mode 100644 index 0000000000..3a9d6c01ab --- /dev/null +++ b/source3/nsswitch/winbind_nss_irix.c @@ -0,0 +1,515 @@ +/* + Unix SMB/CIFS implementation. + + Windows NT Domain nsswitch module + + Copyright (C) Tim Potter 2000 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "winbind_client.h" + +#ifdef HAVE_NS_API_H +#undef VOLATILE +#include +#endif + +/* Maximum number of users to pass back over the unix domain socket + per call. This is not a static limit on the total number of users + or groups returned in total. */ + +#define MAX_GETPWENT_USERS 250 +#define MAX_GETGRENT_USERS 250 + +/* Prototypes from wb_common.c */ + +extern int winbindd_fd; + +#ifdef HAVE_NS_API_H + +/* IRIX version */ + +static int send_next_request(nsd_file_t *, struct winbindd_request *); +static int do_list(int state, nsd_file_t *rq); + +static nsd_file_t *current_rq = NULL; +static int current_winbind_xid = 0; +static int next_winbind_xid = 0; + +typedef struct winbind_xid { + int xid; + nsd_file_t *rq; + struct winbindd_request *request; + struct winbind_xid *next; +} winbind_xid_t; + +static winbind_xid_t *winbind_xids = (winbind_xid_t *)0; + +static int +winbind_xid_new(int xid, nsd_file_t *rq, struct winbindd_request *request) +{ + winbind_xid_t *new; + + nsd_logprintf(NSD_LOG_LOW, + "entering winbind_xid_new xid = %d rq = 0x%x, request = 0x%x\n", + xid, rq, request); + new = (winbind_xid_t *)nsd_calloc(1,sizeof(winbind_xid_t)); + if (!new) { + nsd_logprintf(NSD_LOG_RESOURCE,"winbind_xid_new: failed malloc\n"); + return NSD_ERROR; + } + + new->xid = xid; + new->rq = rq; + new->request = request; + new->next = winbind_xids; + winbind_xids = new; + + return NSD_CONTINUE; +} + +/* +** This routine will look down the xid list and return the request +** associated with an xid. We remove the record if it is found. +*/ +nsd_file_t * +winbind_xid_lookup(int xid, struct winbindd_request **requestp) +{ + winbind_xid_t **last, *dx; + nsd_file_t *result=0; + + for (last = &winbind_xids, dx = winbind_xids; dx && (dx->xid != xid); + last = &dx->next, dx = dx->next); + if (dx) { + *last = dx->next; + result = dx->rq; + *requestp = dx->request; + SAFE_FREE(dx); + } + nsd_logprintf(NSD_LOG_LOW, + "entering winbind_xid_lookup xid = %d rq = 0x%x, request = 0x%x\n", + xid, result, dx->request); + + return result; +} + +static int +winbind_startnext_timeout(nsd_file_t **rqp, nsd_times_t *to) +{ + nsd_file_t *rq; + struct winbindd_request *request; + + nsd_logprintf(NSD_LOG_MIN, "timeout (winbind startnext)\n"); + rq = to->t_file; + *rqp = rq; + nsd_timeout_remove(rq); + request = to->t_clientdata; + return(send_next_request(rq, request)); +} + +static void +dequeue_request() +{ + nsd_file_t *rq; + struct winbindd_request *request; + + /* + * Check for queued requests + */ + if (winbind_xids) { + nsd_logprintf(NSD_LOG_MIN, "timeout (winbind) unqueue xid %d\n", + current_winbind_xid); + rq = winbind_xid_lookup(current_winbind_xid++, &request); + /* cause a timeout on the queued request so we can send it */ + nsd_timeout_new(rq,1,winbind_startnext_timeout,request); + } +} + +static int +do_request(nsd_file_t *rq, struct winbindd_request *request) +{ + if (winbind_xids == NULL) { + /* + * No outstanding requests. + * Send off the request to winbindd + */ + nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) sending request\n"); + return(send_next_request(rq, request)); + } else { + /* + * Just queue it up for now - previous callout or timout + * will start it up + */ + nsd_logprintf(NSD_LOG_MIN, + "lookup (winbind): queue request xid = %d\n", + next_winbind_xid); + return(winbind_xid_new(next_winbind_xid++, rq, request)); + } +} + +static int +winbind_callback(nsd_file_t **rqp, int fd) +{ + struct winbindd_response response; + struct winbindd_pw *pw = &response.data.pw; + struct winbindd_gr *gr = &response.data.gr; + nsd_file_t *rq; + NSS_STATUS status; + fstring result; + char *members; + int i, maxlen; + + dequeue_request(); + + nsd_logprintf(NSD_LOG_MIN, "entering callback (winbind)\n"); + + rq = current_rq; + *rqp = rq; + + nsd_timeout_remove(rq); + nsd_callback_remove(fd); + + ZERO_STRUCT(response); + status = winbindd_get_response(&response); + + if (status != NSS_STATUS_SUCCESS) { + /* free any extra data area in response structure */ + free_response(&response); + nsd_logprintf(NSD_LOG_MIN, + "callback (winbind) returning not found, status = %d\n", + status); + rq->f_status = NS_NOTFOUND; + return NSD_NEXT; + } + + maxlen = sizeof(result) - 1; + + switch ((int)rq->f_cmd_data) { + case WINBINDD_WINS_BYNAME: + case WINBINDD_WINS_BYIP: + snprintf(result,maxlen,"%s\n",response.data.winsresp); + break; + case WINBINDD_GETPWUID: + case WINBINDD_GETPWNAM: + snprintf(result,maxlen,"%s:%s:%d:%d:%s:%s:%s\n", + pw->pw_name, + pw->pw_passwd, + pw->pw_uid, + pw->pw_gid, + pw->pw_gecos, + pw->pw_dir, + pw->pw_shell); + break; + case WINBINDD_GETGRNAM: + case WINBINDD_GETGRGID: + if (gr->num_gr_mem && response.extra_data) + members = response.extra_data; + else + members = ""; + snprintf(result,maxlen,"%s:%s:%d:%s\n", + gr->gr_name, gr->gr_passwd, gr->gr_gid, members); + break; + case WINBINDD_SETGRENT: + case WINBINDD_SETPWENT: + nsd_logprintf(NSD_LOG_MIN, "callback (winbind) - SETPWENT/SETGRENT\n"); + free_response(&response); + return(do_list(1,rq)); + case WINBINDD_GETGRENT: + case WINBINDD_GETGRLST: + nsd_logprintf(NSD_LOG_MIN, + "callback (winbind) - %d GETGRENT responses\n", + response.data.num_entries); + if (response.data.num_entries) { + gr = (struct winbindd_gr *)response.extra_data; + if (! gr ) { + nsd_logprintf(NSD_LOG_MIN, " no extra_data\n"); + free_response(&response); + return NSD_ERROR; + } + members = (char *)response.extra_data + + (response.data.num_entries * sizeof(struct winbindd_gr)); + for (i = 0; i < response.data.num_entries; i++) { + snprintf(result,maxlen,"%s:%s:%d:%s\n", + gr->gr_name, gr->gr_passwd, gr->gr_gid, + &members[gr->gr_mem_ofs]); + nsd_logprintf(NSD_LOG_MIN, " GETGRENT %s\n",result); + nsd_append_element(rq,NS_SUCCESS,result,strlen(result)); + gr++; + } + } + i = response.data.num_entries; + free_response(&response); + if (i < MAX_GETPWENT_USERS) + return(do_list(2,rq)); + else + return(do_list(1,rq)); + case WINBINDD_GETPWENT: + nsd_logprintf(NSD_LOG_MIN, + "callback (winbind) - %d GETPWENT responses\n", + response.data.num_entries); + if (response.data.num_entries) { + pw = (struct winbindd_pw *)response.extra_data; + if (! pw ) { + nsd_logprintf(NSD_LOG_MIN, " no extra_data\n"); + free_response(&response); + return NSD_ERROR; + } + for (i = 0; i < response.data.num_entries; i++) { + snprintf(result,maxlen,"%s:%s:%d:%d:%s:%s:%s", + pw->pw_name, + pw->pw_passwd, + pw->pw_uid, + pw->pw_gid, + pw->pw_gecos, + pw->pw_dir, + pw->pw_shell); + nsd_logprintf(NSD_LOG_MIN, " GETPWENT %s\n",result); + nsd_append_element(rq,NS_SUCCESS,result,strlen(result)); + pw++; + } + } + i = response.data.num_entries; + free_response(&response); + if (i < MAX_GETPWENT_USERS) + return(do_list(2,rq)); + else + return(do_list(1,rq)); + case WINBINDD_ENDGRENT: + case WINBINDD_ENDPWENT: + nsd_logprintf(NSD_LOG_MIN, "callback (winbind) - ENDPWENT/ENDGRENT\n"); + nsd_append_element(rq,NS_SUCCESS,"\n",1); + free_response(&response); + return NSD_NEXT; + default: + free_response(&response); + nsd_logprintf(NSD_LOG_MIN, "callback (winbind) - no valid command\n"); + return NSD_NEXT; + } + nsd_logprintf(NSD_LOG_MIN, "callback (winbind) %s\n", result); + /* free any extra data area in response structure */ + free_response(&response); + nsd_set_result(rq,NS_SUCCESS,result,strlen(result),VOLATILE); + return NSD_OK; +} + +static int +winbind_timeout(nsd_file_t **rqp, nsd_times_t *to) +{ + nsd_file_t *rq; + + dequeue_request(); + + nsd_logprintf(NSD_LOG_MIN, "timeout (winbind)\n"); + + rq = to->t_file; + *rqp = rq; + + /* Remove the callback and timeout */ + nsd_callback_remove(winbindd_fd); + nsd_timeout_remove(rq); + + rq->f_status = NS_NOTFOUND; + return NSD_NEXT; +} + +static int +send_next_request(nsd_file_t *rq, struct winbindd_request *request) +{ + NSS_STATUS status; + long timeout; + + timeout = 1000; + + nsd_logprintf(NSD_LOG_MIN, "send_next_request (winbind) %d to = %d\n", + rq->f_cmd_data, timeout); + status = winbindd_send_request((int)rq->f_cmd_data,request); + SAFE_FREE(request); + + if (status != NSS_STATUS_SUCCESS) { + nsd_logprintf(NSD_LOG_MIN, + "send_next_request (winbind) error status = %d\n",status); + rq->f_status = status; + return NSD_NEXT; + } + + current_rq = rq; + + /* + * Set up callback and timeouts + */ + nsd_logprintf(NSD_LOG_MIN, "send_next_request (winbind) fd = %d\n",winbindd_fd); + nsd_callback_new(winbindd_fd,winbind_callback,NSD_READ); + nsd_timeout_new(rq,timeout,winbind_timeout,(void *)0); + return NSD_CONTINUE; +} + +int init(void) +{ + nsd_logprintf(NSD_LOG_MIN, "entering init (winbind)\n"); + return(NSD_OK); +} + +int lookup(nsd_file_t *rq) +{ + char *map; + char *key; + struct winbindd_request *request; + + nsd_logprintf(NSD_LOG_MIN, "entering lookup (winbind)\n"); + if (! rq) + return NSD_ERROR; + + map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0); + key = nsd_attr_fetch_string(rq->f_attrs, "key", (char*)0); + if (! map || ! key) { + nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) table or key not defined\n"); + rq->f_status = NS_BADREQ; + return NSD_ERROR; + } + + nsd_logprintf(NSD_LOG_MIN, "lookup (winbind %s)\n",map); + + request = (struct winbindd_request *)nsd_calloc(1,sizeof(struct winbindd_request)); + if (! request) { + nsd_logprintf(NSD_LOG_RESOURCE, + "lookup (winbind): failed malloc\n"); + return NSD_ERROR; + } + + if (strcasecmp(map,"passwd.byuid") == 0) { + request->data.uid = atoi(key); + rq->f_cmd_data = (void *)WINBINDD_GETPWUID; + } else if (strcasecmp(map,"passwd.byname") == 0) { + strncpy(request->data.username, key, + sizeof(request->data.username) - 1); + request->data.username[sizeof(request->data.username) - 1] = '\0'; + rq->f_cmd_data = (void *)WINBINDD_GETPWNAM; + } else if (strcasecmp(map,"group.byname") == 0) { + strncpy(request->data.groupname, key, + sizeof(request->data.groupname) - 1); + request->data.groupname[sizeof(request->data.groupname) - 1] = '\0'; + rq->f_cmd_data = (void *)WINBINDD_GETGRNAM; + } else if (strcasecmp(map,"group.bygid") == 0) { + request->data.gid = atoi(key); + rq->f_cmd_data = (void *)WINBINDD_GETGRGID; + } else if (strcasecmp(map,"hosts.byname") == 0) { + strncpy(request->data.winsreq, key, sizeof(request->data.winsreq) - 1); + request->data.winsreq[sizeof(request->data.winsreq) - 1] = '\0'; + rq->f_cmd_data = (void *)WINBINDD_WINS_BYNAME; + } else if (strcasecmp(map,"hosts.byaddr") == 0) { + strncpy(request->data.winsreq, key, sizeof(request->data.winsreq) - 1); + request->data.winsreq[sizeof(request->data.winsreq) - 1] = '\0'; + rq->f_cmd_data = (void *)WINBINDD_WINS_BYIP; + } else { + /* + * Don't understand this map - just return not found + */ + nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) unknown table\n"); + SAFE_FREE(request); + rq->f_status = NS_NOTFOUND; + return NSD_NEXT; + } + + return(do_request(rq, request)); +} + +int list(nsd_file_t *rq) +{ + char *map; + + nsd_logprintf(NSD_LOG_MIN, "entering list (winbind)\n"); + if (! rq) + return NSD_ERROR; + + map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0); + if (! map ) { + nsd_logprintf(NSD_LOG_MIN, "list (winbind) table not defined\n"); + rq->f_status = NS_BADREQ; + return NSD_ERROR; + } + + nsd_logprintf(NSD_LOG_MIN, "list (winbind %s)\n",map); + + return (do_list(0,rq)); +} + +static int +do_list(int state, nsd_file_t *rq) +{ + char *map; + struct winbindd_request *request; + + nsd_logprintf(NSD_LOG_MIN, "entering do_list (winbind) state = %d\n",state); + + map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0); + request = (struct winbindd_request *)nsd_calloc(1,sizeof(struct winbindd_request)); + if (! request) { + nsd_logprintf(NSD_LOG_RESOURCE, + "do_list (winbind): failed malloc\n"); + return NSD_ERROR; + } + + if (strcasecmp(map,"passwd.byname") == 0) { + switch (state) { + case 0: + rq->f_cmd_data = (void *)WINBINDD_SETPWENT; + break; + case 1: + request->data.num_entries = MAX_GETPWENT_USERS; + rq->f_cmd_data = (void *)WINBINDD_GETPWENT; + break; + case 2: + rq->f_cmd_data = (void *)WINBINDD_ENDPWENT; + break; + default: + nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown state\n"); + SAFE_FREE(request); + rq->f_status = NS_NOTFOUND; + return NSD_NEXT; + } + } else if (strcasecmp(map,"group.byname") == 0) { + switch (state) { + case 0: + rq->f_cmd_data = (void *)WINBINDD_SETGRENT; + break; + case 1: + request->data.num_entries = MAX_GETGRENT_USERS; + rq->f_cmd_data = (void *)WINBINDD_GETGRENT; + break; + case 2: + rq->f_cmd_data = (void *)WINBINDD_ENDGRENT; + break; + default: + nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown state\n"); + SAFE_FREE(request); + rq->f_status = NS_NOTFOUND; + return NSD_NEXT; + } + } else { + /* + * Don't understand this map - just return not found + */ + nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown table\n"); + SAFE_FREE(request); + rq->f_status = NS_NOTFOUND; + return NSD_NEXT; + } + + return(do_request(rq, request)); +} + +#endif /* HAVE_NS_API_H */ diff --git a/source3/nsswitch/winbind_nss_irix.h b/source3/nsswitch/winbind_nss_irix.h new file mode 100644 index 0000000000..7878abb981 --- /dev/null +++ b/source3/nsswitch/winbind_nss_irix.h @@ -0,0 +1,48 @@ +/* + Unix SMB/CIFS implementation. + + Winbind daemon for ntdom nss module + + Copyright (C) Tim Potter 2000 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef _WINBIND_NSS_IRIX_H +#define _WINBIND_NSS_IRIX_H + +/* following required to prevent warnings of double definition + * of datum from ns_api.h +*/ +#ifdef DATUM +#define _DATUM_DEFINED +#endif + +#include + +typedef enum +{ + NSS_STATUS_SUCCESS=NS_SUCCESS, + NSS_STATUS_NOTFOUND=NS_NOTFOUND, + NSS_STATUS_UNAVAIL=NS_UNAVAIL, + NSS_STATUS_TRYAGAIN=NS_TRYAGAIN +} NSS_STATUS; + +#define NSD_MEM_STATIC 0 +#define NSD_MEM_VOLATILE 1 +#define NSD_MEM_DYNAMIC 2 + +#endif /* _WINBIND_NSS_IRIX_H */ diff --git a/source3/nsswitch/winbind_nss_linux.c b/source3/nsswitch/winbind_nss_linux.c new file mode 100644 index 0000000000..125bc8ccda --- /dev/null +++ b/source3/nsswitch/winbind_nss_linux.c @@ -0,0 +1,862 @@ +/* + Unix SMB/CIFS implementation. + + Windows NT Domain nsswitch module + + Copyright (C) Tim Potter 2000 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "winbind_client.h" + +/* Maximum number of users to pass back over the unix domain socket + per call. This is not a static limit on the total number of users + or groups returned in total. */ + +#define MAX_GETPWENT_USERS 250 +#define MAX_GETGRENT_USERS 250 + +/* Prototypes from wb_common.c */ + +extern int winbindd_fd; + +/* Allocate some space from the nss static buffer. The buffer and buflen + are the pointers passed in by the C library to the _nss_ntdom_* + functions. */ + +static char *get_static(char **buffer, int *buflen, int len) +{ + char *result; + + /* Error check. We return false if things aren't set up right, or + there isn't enough buffer space left. */ + + if ((buffer == NULL) || (buflen == NULL) || (*buflen < len)) { + return NULL; + } + + /* Return an index into the static buffer */ + + result = *buffer; + *buffer += len; + *buflen -= len; + + return result; +} + +/* I've copied the strtok() replacement function next_token() from + lib/util_str.c as I really don't want to have to link in any other + objects if I can possibly avoid it. */ + +BOOL next_token(char **ptr,char *buff,char *sep, size_t bufsize) +{ + char *s; + BOOL quoted; + size_t len=1; + + if (!ptr) return(False); + + s = *ptr; + + /* default to simple separators */ + if (!sep) sep = " \t\n\r"; + + /* find the first non sep char */ + while (*s && strchr(sep,*s)) s++; + + /* nothing left? */ + if (! *s) return(False); + + /* copy over the token */ + for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++) { + if (*s == '\"') { + quoted = !quoted; + } else { + len++; + *buff++ = *s; + } + } + + *ptr = (*s) ? s+1 : s; + *buff = 0; + + return(True); +} + + +/* Fill a pwent structure from a winbindd_response structure. We use + the static data passed to us by libc to put strings and stuff in. + Return NSS_STATUS_TRYAGAIN if we run out of memory. */ + +static NSS_STATUS fill_pwent(struct passwd *result, + struct winbindd_pw *pw, + char **buffer, size_t *buflen) +{ + /* User name */ + + if ((result->pw_name = + get_static(buffer, buflen, strlen(pw->pw_name) + 1)) == NULL) { + + /* Out of memory */ + + return NSS_STATUS_TRYAGAIN; + } + + strcpy(result->pw_name, pw->pw_name); + + /* Password */ + + if ((result->pw_passwd = + get_static(buffer, buflen, strlen(pw->pw_passwd) + 1)) == NULL) { + + /* Out of memory */ + + return NSS_STATUS_TRYAGAIN; + } + + strcpy(result->pw_passwd, pw->pw_passwd); + + /* [ug]id */ + + result->pw_uid = pw->pw_uid; + result->pw_gid = pw->pw_gid; + + /* GECOS */ + + if ((result->pw_gecos = + get_static(buffer, buflen, strlen(pw->pw_gecos) + 1)) == NULL) { + + /* Out of memory */ + + return NSS_STATUS_TRYAGAIN; + } + + strcpy(result->pw_gecos, pw->pw_gecos); + + /* Home directory */ + + if ((result->pw_dir = + get_static(buffer, buflen, strlen(pw->pw_dir) + 1)) == NULL) { + + /* Out of memory */ + + return NSS_STATUS_TRYAGAIN; + } + + strcpy(result->pw_dir, pw->pw_dir); + + /* Logon shell */ + + if ((result->pw_shell = + get_static(buffer, buflen, strlen(pw->pw_shell) + 1)) == NULL) { + + /* Out of memory */ + + return NSS_STATUS_TRYAGAIN; + } + + strcpy(result->pw_shell, pw->pw_shell); + + /* The struct passwd for Solaris has some extra fields which must + be initialised or nscd crashes. */ + +#if HAVE_PASSWD_PW_COMMENT + result->pw_comment = ""; +#endif + +#if HAVE_PASSWD_PW_AGE + result->pw_age = ""; +#endif + + return NSS_STATUS_SUCCESS; +} + +/* Fill a grent structure from a winbindd_response structure. We use + the static data passed to us by libc to put strings and stuff in. + Return NSS_STATUS_TRYAGAIN if we run out of memory. */ + +static NSS_STATUS fill_grent(struct group *result, struct winbindd_gr *gr, + char *gr_mem, char **buffer, size_t *buflen) +{ + fstring name; + int i; + char *tst; + + /* Group name */ + + if ((result->gr_name = + get_static(buffer, buflen, strlen(gr->gr_name) + 1)) == NULL) { + + /* Out of memory */ + + return NSS_STATUS_TRYAGAIN; + } + + strcpy(result->gr_name, gr->gr_name); + + /* Password */ + + if ((result->gr_passwd = + get_static(buffer, buflen, strlen(gr->gr_passwd) + 1)) == NULL) { + + /* Out of memory */ + + return NSS_STATUS_TRYAGAIN; + } + + strcpy(result->gr_passwd, gr->gr_passwd); + + /* gid */ + + result->gr_gid = gr->gr_gid; + + /* Group membership */ + + if ((gr->num_gr_mem < 0) || !gr_mem) { + gr->num_gr_mem = 0; + } + + /* this next value is a pointer to a pointer so let's align it */ + + /* Calculate number of extra bytes needed to align on pointer size boundry */ + if ((i = (unsigned long)(*buffer) % sizeof(char*)) != 0) + i = sizeof(char*) - i; + + if ((tst = get_static(buffer, buflen, ((gr->num_gr_mem + 1) * + sizeof(char *)+i))) == NULL) { + + /* Out of memory */ + + return NSS_STATUS_TRYAGAIN; + } + result->gr_mem = (char **)(tst + i); + + if (gr->num_gr_mem == 0) { + + /* Group is empty */ + + *(result->gr_mem) = NULL; + return NSS_STATUS_SUCCESS; + } + + /* Start looking at extra data */ + + i = 0; + + while(next_token((char **)&gr_mem, name, ",", sizeof(fstring))) { + + /* Allocate space for member */ + + if (((result->gr_mem)[i] = + get_static(buffer, buflen, strlen(name) + 1)) == NULL) { + + /* Out of memory */ + + return NSS_STATUS_TRYAGAIN; + } + + strcpy((result->gr_mem)[i], name); + i++; + } + + /* Terminate list */ + + (result->gr_mem)[i] = NULL; + + return NSS_STATUS_SUCCESS; +} + +/* + * NSS user functions + */ + +static struct winbindd_response getpwent_response; + +static int ndx_pw_cache; /* Current index into pwd cache */ +static int num_pw_cache; /* Current size of pwd cache */ + +/* Rewind "file pointer" to start of ntdom password database */ + +NSS_STATUS +_nss_winbind_setpwent(void) +{ +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: setpwent\n", getpid()); +#endif + + if (num_pw_cache > 0) { + ndx_pw_cache = num_pw_cache = 0; + free_response(&getpwent_response); + } + + return winbindd_request(WINBINDD_SETPWENT, NULL, NULL); +} + +/* Close ntdom password database "file pointer" */ + +NSS_STATUS +_nss_winbind_endpwent(void) +{ +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: endpwent\n", getpid()); +#endif + + if (num_pw_cache > 0) { + ndx_pw_cache = num_pw_cache = 0; + free_response(&getpwent_response); + } + + return winbindd_request(WINBINDD_ENDPWENT, NULL, NULL); +} + +/* Fetch the next password entry from ntdom password database */ + +NSS_STATUS +_nss_winbind_getpwent_r(struct passwd *result, char *buffer, + size_t buflen, int *errnop) +{ + NSS_STATUS ret; + struct winbindd_request request; + static int called_again; + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: getpwent\n", getpid()); +#endif + + /* Return an entry from the cache if we have one, or if we are + called again because we exceeded our static buffer. */ + + if ((ndx_pw_cache < num_pw_cache) || called_again) { + goto return_result; + } + + /* Else call winbindd to get a bunch of entries */ + + if (num_pw_cache > 0) { + free_response(&getpwent_response); + } + + ZERO_STRUCT(request); + ZERO_STRUCT(getpwent_response); + + request.data.num_entries = MAX_GETPWENT_USERS; + + ret = winbindd_request(WINBINDD_GETPWENT, &request, + &getpwent_response); + + if (ret == NSS_STATUS_SUCCESS) { + struct winbindd_pw *pw_cache; + + /* Fill cache */ + + ndx_pw_cache = 0; + num_pw_cache = getpwent_response.data.num_entries; + + /* Return a result */ + + return_result: + + pw_cache = getpwent_response.extra_data; + + /* Check data is valid */ + + if (pw_cache == NULL) { + return NSS_STATUS_NOTFOUND; + } + + ret = fill_pwent(result, &pw_cache[ndx_pw_cache], + &buffer, &buflen); + + /* Out of memory - try again */ + + if (ret == NSS_STATUS_TRYAGAIN) { + called_again = True; + *errnop = errno = ERANGE; + return ret; + } + + *errnop = errno = 0; + called_again = False; + ndx_pw_cache++; + + /* If we've finished with this lot of results free cache */ + + if (ndx_pw_cache == num_pw_cache) { + ndx_pw_cache = num_pw_cache = 0; + free_response(&getpwent_response); + } + } + + return ret; +} + +/* Return passwd struct from uid */ + +NSS_STATUS +_nss_winbind_getpwuid_r(uid_t uid, struct passwd *result, char *buffer, + size_t buflen, int *errnop) +{ + NSS_STATUS ret; + static struct winbindd_response response; + struct winbindd_request request; + static int keep_response=0; + + /* If our static buffer needs to be expanded we are called again */ + if (!keep_response) { + + /* Call for the first time */ + + ZERO_STRUCT(response); + ZERO_STRUCT(request); + + request.data.uid = uid; + + ret = winbindd_request(WINBINDD_GETPWUID, &request, &response); + + if (ret == NSS_STATUS_SUCCESS) { + ret = fill_pwent(result, &response.data.pw, + &buffer, &buflen); + + if (ret == NSS_STATUS_TRYAGAIN) { + keep_response = True; + *errnop = errno = ERANGE; + return ret; + } + } + + } else { + + /* We've been called again */ + + ret = fill_pwent(result, &response.data.pw, &buffer, &buflen); + + if (ret == NSS_STATUS_TRYAGAIN) { + keep_response = True; + *errnop = errno = ERANGE; + return ret; + } + + keep_response = False; + *errnop = errno = 0; + } + + free_response(&response); + return ret; +} + +/* Return passwd struct from username */ + +NSS_STATUS +_nss_winbind_getpwnam_r(const char *name, struct passwd *result, char *buffer, + size_t buflen, int *errnop) +{ + NSS_STATUS ret; + static struct winbindd_response response; + struct winbindd_request request; + static int keep_response; + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: getpwnam %s\n", getpid(), name); +#endif + + /* If our static buffer needs to be expanded we are called again */ + + if (!keep_response) { + + /* Call for the first time */ + + ZERO_STRUCT(response); + ZERO_STRUCT(request); + + strncpy(request.data.username, name, + sizeof(request.data.username) - 1); + request.data.username + [sizeof(request.data.username) - 1] = '\0'; + + ret = winbindd_request(WINBINDD_GETPWNAM, &request, &response); + + if (ret == NSS_STATUS_SUCCESS) { + ret = fill_pwent(result, &response.data.pw, &buffer, + &buflen); + + if (ret == NSS_STATUS_TRYAGAIN) { + keep_response = True; + *errnop = errno = ERANGE; + return ret; + } + } + + } else { + + /* We've been called again */ + + ret = fill_pwent(result, &response.data.pw, &buffer, &buflen); + + if (ret == NSS_STATUS_TRYAGAIN) { + keep_response = True; + *errnop = errno = ERANGE; + return ret; + } + + keep_response = False; + *errnop = errno = 0; + } + + free_response(&response); + return ret; +} + +/* + * NSS group functions + */ + +static struct winbindd_response getgrent_response; + +static int ndx_gr_cache; /* Current index into grp cache */ +static int num_gr_cache; /* Current size of grp cache */ + +/* Rewind "file pointer" to start of ntdom group database */ + +NSS_STATUS +_nss_winbind_setgrent(void) +{ +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: setgrent\n", getpid()); +#endif + + if (num_gr_cache > 0) { + ndx_gr_cache = num_gr_cache = 0; + free_response(&getgrent_response); + } + + return winbindd_request(WINBINDD_SETGRENT, NULL, NULL); +} + +/* Close "file pointer" for ntdom group database */ + +NSS_STATUS +_nss_winbind_endgrent(void) +{ +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: endgrent\n", getpid()); +#endif + + if (num_gr_cache > 0) { + ndx_gr_cache = num_gr_cache = 0; + free_response(&getgrent_response); + } + + return winbindd_request(WINBINDD_ENDGRENT, NULL, NULL); +} + +/* Get next entry from ntdom group database */ + +static NSS_STATUS +winbind_getgrent(enum winbindd_cmd cmd, + struct group *result, + char *buffer, size_t buflen, int *errnop) +{ + NSS_STATUS ret; + static struct winbindd_request request; + static int called_again; + + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: getgrent\n", getpid()); +#endif + + /* Return an entry from the cache if we have one, or if we are + called again because we exceeded our static buffer. */ + + if ((ndx_gr_cache < num_gr_cache) || called_again) { + goto return_result; + } + + /* Else call winbindd to get a bunch of entries */ + + if (num_gr_cache > 0) { + free_response(&getgrent_response); + } + + ZERO_STRUCT(request); + ZERO_STRUCT(getgrent_response); + + request.data.num_entries = MAX_GETGRENT_USERS; + + ret = winbindd_request(cmd, &request, + &getgrent_response); + + if (ret == NSS_STATUS_SUCCESS) { + struct winbindd_gr *gr_cache; + int mem_ofs; + + /* Fill cache */ + + ndx_gr_cache = 0; + num_gr_cache = getgrent_response.data.num_entries; + + /* Return a result */ + + return_result: + + gr_cache = getgrent_response.extra_data; + + /* Check data is valid */ + + if (gr_cache == NULL) { + return NSS_STATUS_NOTFOUND; + } + + /* Fill group membership. The offset into the extra data + for the group membership is the reported offset plus the + size of all the winbindd_gr records returned. */ + + mem_ofs = gr_cache[ndx_gr_cache].gr_mem_ofs + + num_gr_cache * sizeof(struct winbindd_gr); + + ret = fill_grent(result, &gr_cache[ndx_gr_cache], + ((char *)getgrent_response.extra_data)+mem_ofs, + &buffer, &buflen); + + /* Out of memory - try again */ + + if (ret == NSS_STATUS_TRYAGAIN) { + called_again = True; + *errnop = errno = ERANGE; + return ret; + } + + *errnop = 0; + called_again = False; + ndx_gr_cache++; + + /* If we've finished with this lot of results free cache */ + + if (ndx_gr_cache == num_gr_cache) { + ndx_gr_cache = num_gr_cache = 0; + free_response(&getgrent_response); + } + } + + return ret; +} + + +NSS_STATUS +_nss_winbind_getgrent_r(struct group *result, + char *buffer, size_t buflen, int *errnop) +{ + return winbind_getgrent(WINBINDD_GETGRENT, result, buffer, buflen, errnop); +} + +NSS_STATUS +_nss_winbind_getgrlst_r(struct group *result, + char *buffer, size_t buflen, int *errnop) +{ + return winbind_getgrent(WINBINDD_GETGRLST, result, buffer, buflen, errnop); +} + +/* Return group struct from group name */ + +NSS_STATUS +_nss_winbind_getgrnam_r(const char *name, + struct group *result, char *buffer, + size_t buflen, int *errnop) +{ + NSS_STATUS ret; + static struct winbindd_response response; + struct winbindd_request request; + static int keep_response; + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: getgrnam %s\n", getpid(), name); +#endif + + /* If our static buffer needs to be expanded we are called again */ + + if (!keep_response) { + + /* Call for the first time */ + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + strncpy(request.data.groupname, name, + sizeof(request.data.groupname)); + request.data.groupname + [sizeof(request.data.groupname) - 1] = '\0'; + + ret = winbindd_request(WINBINDD_GETGRNAM, &request, &response); + + if (ret == NSS_STATUS_SUCCESS) { + ret = fill_grent(result, &response.data.gr, + response.extra_data, + &buffer, &buflen); + + if (ret == NSS_STATUS_TRYAGAIN) { + keep_response = True; + *errnop = errno = ERANGE; + return ret; + } + } + + } else { + + /* We've been called again */ + + ret = fill_grent(result, &response.data.gr, + response.extra_data, &buffer, &buflen); + + if (ret == NSS_STATUS_TRYAGAIN) { + keep_response = True; + *errnop = errno = ERANGE; + return ret; + } + + keep_response = False; + *errnop = 0; + } + + free_response(&response); + return ret; +} + +/* Return group struct from gid */ + +NSS_STATUS +_nss_winbind_getgrgid_r(gid_t gid, + struct group *result, char *buffer, + size_t buflen, int *errnop) +{ + NSS_STATUS ret; + static struct winbindd_response response; + struct winbindd_request request; + static int keep_response; + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: getgrgid %d\n", getpid(), gid); +#endif + + /* If our static buffer needs to be expanded we are called again */ + + if (!keep_response) { + + /* Call for the first time */ + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + request.data.gid = gid; + + ret = winbindd_request(WINBINDD_GETGRGID, &request, &response); + + if (ret == NSS_STATUS_SUCCESS) { + + ret = fill_grent(result, &response.data.gr, + response.extra_data, + &buffer, &buflen); + + if (ret == NSS_STATUS_TRYAGAIN) { + keep_response = True; + *errnop = errno = ERANGE; + return ret; + } + } + + } else { + + /* We've been called again */ + + ret = fill_grent(result, &response.data.gr, + response.extra_data, &buffer, &buflen); + + if (ret == NSS_STATUS_TRYAGAIN) { + keep_response = True; + *errnop = errno = ERANGE; + return ret; + } + + keep_response = False; + *errnop = 0; + } + + free_response(&response); + return ret; +} + +/* Initialise supplementary groups */ + +NSS_STATUS +_nss_winbind_initgroups_dyn(char *user, gid_t group, long int *start, + long int *size, gid_t **groups, long int limit, + int *errnop) +{ + NSS_STATUS ret; + struct winbindd_request request; + struct winbindd_response response; + int i; + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: initgroups %s (%d)\n", getpid(), + user, group); +#endif + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + strncpy(request.data.username, user, + sizeof(request.data.username) - 1); + + ret = winbindd_request(WINBINDD_GETGROUPS, &request, &response); + + if (ret == NSS_STATUS_SUCCESS) { + int num_gids = response.data.num_entries; + gid_t *gid_list = (gid_t *)response.extra_data; + + /* Copy group list to client */ + + for (i = 0; i < num_gids; i++) { + + /* Skip primary group */ + + if (gid_list[i] == group) continue; + + /* Add to buffer */ + + if (*start == *size && limit <= 0) { + (*groups) = realloc( + (*groups), (2 * (*size) + 1) * sizeof(**groups)); + if (! *groups) goto done; + *size = 2 * (*size) + 1; + } + + if (*start == *size) goto done; + + (*groups)[*start] = gid_list[i]; + *start += 1; + + /* Filled buffer? */ + + if (*start == limit) goto done; + } + } + + /* Back to your regularly scheduled programming */ + + done: + return ret; +} diff --git a/source3/nsswitch/winbind_nss_linux.h b/source3/nsswitch/winbind_nss_linux.h new file mode 100644 index 0000000000..1c7e830037 --- /dev/null +++ b/source3/nsswitch/winbind_nss_linux.h @@ -0,0 +1,35 @@ +/* + Unix SMB/CIFS implementation. + + Winbind daemon for ntdom nss module + + Copyright (C) Tim Potter 2000 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef _WINBIND_NSS_LINUX_H +#define _WINBIND_NSS_LINUX_H + +#if HAVE_NSS_H + +#include + +typedef enum nss_status NSS_STATUS; + +#endif /* HAVE_NSS_H */ + +#endif /* _WINBIND_NSS_LINUX_H */ diff --git a/source3/nsswitch/winbind_nss_solaris.c b/source3/nsswitch/winbind_nss_solaris.c index f3bd05b77a..6671090e6a 100644 --- a/source3/nsswitch/winbind_nss_solaris.c +++ b/source3/nsswitch/winbind_nss_solaris.c @@ -297,5 +297,3 @@ _nss_winbind_group_constr (const char* db_name, } #endif /* SUN_NSS */ - - diff --git a/source3/nsswitch/winbind_nss_solaris.h b/source3/nsswitch/winbind_nss_solaris.h new file mode 100644 index 0000000000..567de411aa --- /dev/null +++ b/source3/nsswitch/winbind_nss_solaris.h @@ -0,0 +1,61 @@ +/* + Unix SMB/CIFS implementation. + + Winbind daemon for ntdom nss module + + Copyright (C) Tim Potter 2000 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef _WINBIND_NSS_SOLARIS_H +#define _WINBIND_NSS_SOLARIS_H + +#include +#include +#include + +typedef nss_status_t NSS_STATUS; + +#define NSS_STATUS_SUCCESS NSS_SUCCESS +#define NSS_STATUS_NOTFOUND NSS_NOTFOUND +#define NSS_STATUS_UNAVAIL NSS_UNAVAIL +#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN + +/* The solaris winbind is implemented as a wrapper around the linux + version. */ + +NSS_STATUS _nss_winbind_setpwent(void); +NSS_STATUS _nss_winbind_endpwent(void); +NSS_STATUS _nss_winbind_getpwent_r(struct passwd* result, char* buffer, + size_t buflen, int* errnop); +NSS_STATUS _nss_winbind_getpwuid_r(uid_t, struct passwd*, char* buffer, + size_t buflen, int* errnop); +NSS_STATUS _nss_winbind_getpwnam_r(const char* name, struct passwd* result, + char* buffer, size_t buflen, int* errnop); + +NSS_STATUS _nss_winbind_setgrent(void); +NSS_STATUS _nss_winbind_endgrent(void); +NSS_STATUS _nss_winbind_getgrent_r(struct group* result, char* buffer, + size_t buflen, int* errnop); +NSS_STATUS _nss_winbind_getgrnam_r(const char *name, + struct group *result, char *buffer, + size_t buflen, int *errnop); +NSS_STATUS _nss_winbind_getgrgid_r(gid_t gid, + struct group *result, char *buffer, + size_t buflen, int *errnop); + +#endif /* _WINBIND_NSS_SOLARIS_H */ -- cgit From 364519a84332107e15d5586dd082ec9806572e51 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 31 Mar 2003 05:46:32 +0000 Subject: autoconf change to compile winbindd for AIX. The client side code is still under development. (This used to be commit d110a56e433fd2ed5267c6d445b7a652d52940dc) --- source3/configure.in | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3') diff --git a/source3/configure.in b/source3/configure.in index 0e5733ca5c..7b74b6f3ef 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -3184,6 +3184,10 @@ case "$host_os" in HAVE_WINBIND=yes WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_solaris.o" ;; + *aix*) + HAVE_WINBIND=yes + WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_aix.o" + ;; *) HAVE_WINBIND=no winbind_no_reason=", unsupported on $host_os" -- cgit From 2f79b170c827f3c7f0fab05fba7d90d6a1b30949 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 31 Mar 2003 05:47:59 +0000 Subject: Placeholder for winbind aix client. (This used to be commit 872b2ba35bbe9f4312530368615e99808b3a7756) --- source3/nsswitch/winbind_nss_aix.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 source3/nsswitch/winbind_nss_aix.c (limited to 'source3') diff --git a/source3/nsswitch/winbind_nss_aix.c b/source3/nsswitch/winbind_nss_aix.c new file mode 100644 index 0000000000..e69de29bb2 -- cgit From 836454ed58709f92a2b731f118532bab7d012e34 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 31 Mar 2003 05:51:41 +0000 Subject: Tidyup of winbindd client OS specific autoconf code. (This used to be commit b20b8d050b45846798a6dc535cfcd4a47ba21694) --- source3/configure.in | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'source3') diff --git a/source3/configure.in b/source3/configure.in index 7b74b6f3ef..20c3b2ef04 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -3165,27 +3165,26 @@ AC_MSG_CHECKING(whether to build winbind) # Initially, the value of $host_os decides whether winbind is supported +HAVE_WINBIND=yes + case "$host_os" in *linux*) - HAVE_WINBIND=yes WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_linux.o" ;; *irix*) - HAVE_WINBIND=yes WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_irix.o" ;; *solaris*) - HAVE_WINBIND=yes + # Solaris winbind client is implemented as a wrapper around + # the Linux version. WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_solaris.o \ nsswitch/winbind_nss_linux.o" WINBIND_NSS_EXTRA_LIBS="-lsocket" ;; *hpux11*) - HAVE_WINBIND=yes WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_solaris.o" ;; *aix*) - HAVE_WINBIND=yes WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_aix.o" ;; *) -- cgit From 1e4aaa5a7210f6da9762bd12811841668d5fdc3f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 31 Mar 2003 08:14:37 +0000 Subject: Fix a botched merge from appliance-head... We have an extra NULL here, which is (if I understand correctly) related to a optional 'charset conversion' function. In any case, as this is a variable args length function, the compiler didn't pick it up. Would it be possible to change applicance_head (or even HEAD) in such a way that this extra arg would cause a warning? Finding this by testing is getting painful... Andrew Bartlett (This used to be commit b4e52d90f8a207b5cd7415abb5915c3ac0c65dfc) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index b6c4969761..cff6eb62ef 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -835,7 +835,7 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct /* Work out the size. */ data.dsize = 0; - data.dsize += tdb_pack(NULL, 0, NULL, "d", qcount); + data.dsize += tdb_pack(NULL, 0, "d", qcount); for (i = 0; i < pts->qcount; i++) { data.dsize += tdb_pack(NULL, 0, "ddddddff", -- cgit From 52548753296d6929a663adeca2d981c3d5b27351 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 31 Mar 2003 10:44:21 +0000 Subject: Waider's cosmetic change to print out the database type when downloading stuff. Volker (This used to be commit b86ea50fa6dae04adeef750cdbe606a292c1430a) --- source3/utils/net_rpc_samsync.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index 33f4e4b915..e42c8f5637 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -750,6 +750,9 @@ fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta, fetch_alias_mem(hdr_delta->target_rid, &delta->als_mem_info, dom_sid); break; + case SAM_DELTA_DOMAIN_INFO: + d_printf("SAMBA_DELTA_DOMAIN_INFO not handled\n"); + break; default: d_printf("Unknown delta record type %d\n", hdr_delta->type); break; @@ -772,7 +775,20 @@ fetch_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds, return; } - d_printf("Fetching database %u\n", db_type); + switch( db_type ) { + case SAM_DATABASE_DOMAIN: + d_printf("Fetching DOMAIN database\n"); + break; + case SAM_DATABASE_BUILTIN: + d_printf("Fetching BUILTIN database\n"); + break; + case SAM_DATABASE_PRIVS: + d_printf("Fetching PRIVS databases\n"); + break; + default: + d_printf("Fetching unknown database type %u\n", db_type ); + break; + } do { result = cli_netlogon_sam_sync(cli, mem_ctx, ret_creds, -- cgit From b5622cd977089ea8da605eff18e226985fc581ef Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 31 Mar 2003 11:02:22 +0000 Subject: 3 things: * Remove 'ldap del only sam attr' after asking Lars Mueller from SuSE first. It is replaced by 'ldap delete dn' * Fix a typo in docs. * Document 'set primary group script'. Alexander, could you check the file in smbdotconf/ please? Thanks. Volker (This used to be commit f0a32b9c1bdec504ec285486adc05936547f6dc5) --- source3/param/loadparm.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3') diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index d17db16381..9d5d279b31 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -1044,7 +1044,6 @@ static struct parm_struct parm_table[] = { {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED | FLAG_DEVELOPER}, {"ldap trust ids", P_BOOL, P_GLOBAL, &Globals.ldap_trust_ids, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"ldap del only sam attr", P_BOOLREV, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"Miscellaneous Options", P_SEP, P_SEPARATOR}, {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, -- cgit From 8bb5a02f8c2dda5e6045bec37f7befe536042d11 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 31 Mar 2003 12:29:50 +0000 Subject: Fix formatting of back traces - pathc by metze (This used to be commit 9cc17bcfe633496ba6270fd82963ff768ae017b0) --- source3/lib/util.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/lib/util.c b/source3/lib/util.c index da98f5a3cf..3ecfc92552 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -1431,16 +1431,17 @@ void smb_panic(const char *why) WEXITSTATUS(result))); } DEBUG(0,("PANIC: %s\n", why)); - DEBUG(0, ("%d stack frames:\n", backtrace_size)); #ifdef HAVE_BACKTRACE_SYMBOLS /* get the backtrace (stack frames) */ backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE); backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size); + + DEBUG(0, ("BACKTRACE: %d stack frames:\n", backtrace_size)); if (backtrace_strings) { for (i = 0; i < backtrace_size; i++) - DEBUG(0, (" #%u %s\n", i, backtrace_strings[i])); + DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i])); SAFE_FREE(backtrace_strings); } -- cgit From 96b5d5bdfdfe368cb1a84c9b25b2de97c1370af0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 31 Mar 2003 15:06:34 +0000 Subject: - Support absolute paths in vfs and charset modules - Fix typo in Makefile.in - Fix compatibility with older vfs modules (from patch by metze) - Build some modules shared by default and some static (and fall back to static when dlopen() is not available) (This used to be commit aa36f462d95f8a3a3a81a89c210b98a6f9fd295f) --- source3/Makefile.in | 2 +- source3/configure.in | 27 ++++++++++++++++++++------- source3/lib/iconv.c | 9 ++++++--- source3/lib/module.c | 2 +- source3/smbd/conn.c | 4 ++-- source3/smbd/vfs.c | 29 ++++++++++++++++++----------- 6 files changed, 48 insertions(+), 25 deletions(-) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index 75a8db30c2..b05e7692cd 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1028,7 +1028,7 @@ bin/audit.@SHLIBEXT@: $(VFS_AUDIT_OBJ) bin/extd_audit.@SHLIBEXT@: $(VFS_EXTD_AUDIT_OBJ) @echo "Building plugin $@" - @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_AUDIT_OBJ) \ + @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_EXTD_AUDIT_OBJ) \ @SONAMEFLAG@`basename $@` bin/recycle.@SHLIBEXT@: $(VFS_RECYCLE_OBJ) diff --git a/source3/configure.in b/source3/configure.in index 20c3b2ef04..98e01f5bd5 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -239,7 +239,11 @@ AC_VALIDATE_CACHE_SYSTEM_TYPE DYNEXP= dnl Add modules that have to be built by default here -default_modules="pdb_smbpasswd pdb_tdbsam pdb_unix rpc_lsa rpc_samr rpc_reg rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin vfs_recycle vfs_audit vfs_extd_audit vfs_fake_perms vfs_netatalk" +dnl These have to be built static: +default_static_modules="pdb_smbpasswd pdb_tdbsam pdb_unix rpc_lsa rpc_samr rpc_reg rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin" + +dnl These are preferably build shared, and static if dlopen() is not available +default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_fake_perms vfs_netatalk" # # Config CPPFLAG settings for strange OS's that must be set @@ -2255,7 +2259,7 @@ if test x"$with_ldap_support" = x"yes"; then if test x$have_ldap != xyes; then AC_CHECK_LIB(ldap, ldap_domain2hostlist, [LIBS="$LIBS -lldap"; AC_DEFINE(HAVE_LDAP,1,[Whether ldap is available])]) - AC_CHECK_HEADERS([ldap.h lber.h], [default_modules="$default_modules pdb_ldap"]) + AC_CHECK_HEADERS([ldap.h lber.h], [default_static_modules="$default_static_modules pdb_ldap"]) ######################################################## # If we have LDAP, does it's rebind procedure take 2 or 3 arguments? @@ -2272,11 +2276,11 @@ fi ######################################################## # Compile with MySQL support? -AM_PATH_MYSQL([0.11.0],[default_modules="$default_modules pdb_mysql"],[]) +AM_PATH_MYSQL([0.11.0],[default_shared_modules="$default_shared_modules pdb_mysql"],[]) ######################################################## # Compile with XML support? -AM_PATH_XML2([2.0.0],[default_modules="$default_modules pdb_xml"],[]) +AM_PATH_XML2([2.0.0],[default_shared_modules="$default_shared_modules pdb_xml"],[]) ################################################# # check for automount support @@ -3333,13 +3337,22 @@ AC_ARG_WITH(python, esac ]) AC_SUBST(PYTHON) -for i in `echo $default_modules | sed -e's/,/ /g'` +for i in `echo $default_static_modules | sed -e's/,/ /g'` do - dnl Set to shared instead of static when dlopen() is available? eval MODULE_DEFAULT_$i=STATIC done -# Always built these modules static +for i in `echo $default_shared_modules | sed -e's/,/ /g'` +do + dnl Fall back to static if dlopen() is not available + eval MODULE_DEFAULT_$i=STATIC + + if test x"$ac_cv_func_dlopen" = xyes; then + eval MODULE_DEFAULT_$i=SHARED + fi +done + +dnl Always built these modules static MODULE_pdb_guest=STATIC MODULE_rpc_spoolss=STATIC MODULE_rpc_srv=STATIC diff --git a/source3/lib/iconv.c b/source3/lib/iconv.c index 6a397f2d9e..a37441b9fa 100644 --- a/source3/lib/iconv.c +++ b/source3/lib/iconv.c @@ -66,8 +66,12 @@ static struct charset_functions *charsets = NULL; static struct charset_functions *find_charset_functions(const char *name) { struct charset_functions *c = charsets; + pstring stripped; + + module_path_get_name(name, stripped); + while(c) { - if (strcasecmp(name, c->name) == 0)return c; + if (strequal(stripped, c->name) == 0)return c; c = c->next; } @@ -103,9 +107,8 @@ void lazy_initialize_iconv(void) initialized = True; for(i = 0; builtin_functions[i].name; i++) smb_register_charset(&builtin_functions[i]); + static_init_charset; } - - static_init_charset; } /* if there was an error then reset the internal state, diff --git a/source3/lib/module.c b/source3/lib/module.c index e400945a8b..700de56953 100644 --- a/source3/lib/module.c +++ b/source3/lib/module.c @@ -132,7 +132,7 @@ void module_path_get_name(char *path, pstring name) char *s; /* First, make the path relative */ - s = strrchr_m(path, '/'); + s = strrchr(path, '/'); if(s) pstrcpy(name, s+1); else pstrcpy(name, path); diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c index 2a77e23e73..b6c7aa1076 100644 --- a/source3/smbd/conn.c +++ b/source3/smbd/conn.c @@ -201,10 +201,11 @@ void conn_free(connection_struct *conn) /* Free vfs_connection_struct */ handle = conn->vfs_private; while(handle) { + /* Only call dlclose for the old modules */ if (handle->handle) { /* Close dlopen() handle */ done_fptr = (void (*)(connection_struct *))sys_dlsym(handle->handle, "vfs_done"); - + if (done_fptr == NULL) { DEBUG(3, ("No vfs_done() symbol found in module with handle %p, ignoring\n", handle->handle)); } else { @@ -212,7 +213,6 @@ void conn_free(connection_struct *conn) } sys_dlclose(handle->handle); } - DLIST_REMOVE(conn->vfs_private, handle); thandle = handle->next; SAFE_FREE(handle); diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 119e2e2f9a..465d14abba 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -141,9 +141,12 @@ static struct vfs_ops default_vfs_ops = { struct vfs_init_function_entry *vfs_find_backend_entry(const char *name) { struct vfs_init_function_entry *entry = backends; + pstring stripped; + + module_path_get_name(name, stripped); while(entry) { - if (strequal(entry->name, name)) return entry; + if (strequal(entry->name, stripped)) return entry; entry = entry->next; } @@ -200,7 +203,7 @@ static void vfs_init_default(connection_struct *conn) Function to load old VFS modules. Should go away after a while. **************************************************************************/ -static BOOL vfs_load_old_plugin(connection_struct *conn, const char *vfs_object) +static vfs_op_tuple *vfs_load_old_plugin(connection_struct *conn, const char *vfs_object) { int vfs_version = -1; vfs_op_tuple *ops, *(*init_fptr)(int *, const struct vfs_ops *, struct smb_vfs_handle_struct *); @@ -208,7 +211,7 @@ static BOOL vfs_load_old_plugin(connection_struct *conn, const char *vfs_object) if ((conn->vfs_private->handle = sys_dlopen(vfs_object, RTLD_NOW)) == NULL) { DEBUG(0, ("Error opening %s: %s\n", vfs_object, sys_dlerror())); - return False; + return NULL; } /* Get handle on vfs_init() symbol */ @@ -218,21 +221,21 @@ static BOOL vfs_load_old_plugin(connection_struct *conn, const char *vfs_object) if (init_fptr == NULL) { DEBUG(0, ("No vfs_init() symbol found in %s\n", vfs_object)); sys_dlclose(conn->vfs_private->handle); - return False; + return NULL; } /* Initialise vfs_ops structure */ if ((ops = init_fptr(&vfs_version, &conn->vfs_ops, conn->vfs_private)) == NULL) { DEBUG(0, ("vfs_init() function from %s failed\n", vfs_object)); sys_dlclose(conn->vfs_private->handle); - return False; + return NULL; } if ((vfs_version < SMB_VFS_INTERFACE_CASCADED)) { DEBUG(0, ("vfs_init() returned wrong interface version info (was %d, should be no less than %d)\n", vfs_version, SMB_VFS_INTERFACE_VERSION )); sys_dlclose(conn->vfs_private->handle); - return False; + return NULL; } if ((vfs_version < SMB_VFS_INTERFACE_VERSION)) { @@ -240,10 +243,10 @@ static BOOL vfs_load_old_plugin(connection_struct *conn, const char *vfs_object) Proceeding in compatibility mode, new operations (since version #%d) will fallback to default ones.\n", vfs_version, SMB_VFS_INTERFACE_VERSION, vfs_version )); sys_dlclose(conn->vfs_private->handle); - return False; + return NULL; } - return True; + return ops; } @@ -277,10 +280,14 @@ BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object) /* If that doesn't work, fall back to the old system * (This part should go away after a while, it's only here * for backwards compatibility) */ - DEBUG(2, ("Can't load module with new modules system, falling back to old\n")); - if (!vfs_load_old_plugin(conn, vfs_object)) return False; + DEBUG(2, ("Can't load module %s with new modules system, falling back to compatibility\n", + vfs_object)); + if ((ops = vfs_load_old_plugin(conn, vfs_object)) == NULL) { + DEBUG(0, ("vfs init function from %s failed\n", vfs_object)); + return False; + } } - + for(i=0; ops[i].op != NULL; i++) { DEBUG(3, ("Checking operation #%d (type %d, layer %d)\n", i, ops[i].type, ops[i].layer)); if(ops[i].layer == SMB_VFS_LAYER_OPAQUE) { -- cgit From 9d3b00b4bf34438ae8cd8383de9156db70f8435c Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Mon, 31 Mar 2003 16:27:11 +0000 Subject: Fix vfs to work with P_LIST-ed lp_vfsobj() -- the traversal is reversed. Based on patch from Metze (This used to be commit 2a86ef78282d33e16007d50095614713189ce4b5) --- source3/smbd/vfs.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source3') diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 465d14abba..adbde4994d 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -314,8 +314,8 @@ BOOL smbd_vfs_init(connection_struct *conn) { const char **vfs_objects; char *vfs_module, *vfs_path; - unsigned int i; - unsigned int j = 0; + unsigned int i = 0; + int j = 0; struct smb_vfs_handle_struct *handle; /* Normal share - initialise with disk access functions */ @@ -334,7 +334,9 @@ BOOL smbd_vfs_init(connection_struct *conn) vfs_path = lp_vfs_path(SNUM(conn)); - for (j=0; vfs_objects[j]; j++) { + for (i=0; vfs_objects[i]; i++); /* count passed modules */ + + for (j=i-1; j >= 0; j--) { conn->vfs_private = NULL; handle = (struct smb_vfs_handle_struct *) smb_xmalloc(sizeof(smb_vfs_handle_struct)); /* Loadable object file */ -- cgit From b5733dd6ef7c006b0ffc0e6a3c58c30a5d12a585 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 31 Mar 2003 17:39:21 +0000 Subject: fix potential smbd crash when we fail to alloacte a policy handle for a printer open; CR 2102 (reviewed by jreilly) (This used to be commit a179c2cefb15b1b8869a83fe5f14a85d1eb96114) --- source3/rpc_server/srv_spoolss_nt.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'source3') diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 99711cbb13..9c9dd438b3 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -519,21 +519,22 @@ static BOOL open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint3 ZERO_STRUCTP(new_printer); - if ( !(new_printer->ctx = talloc_init("Printer Entry [0x%x]", (uint32)hnd)) ) { - DEBUG(0,("open_printer_hnd: talloc_init() failed!\n")); + if (!create_policy_hnd(p, hnd, free_printer_entry, new_printer)) { + SAFE_FREE(new_printer); return False; } - new_printer->notify.option=NULL; - /* Add to the internal list. */ DLIST_ADD(printers_list, new_printer); - - if (!create_policy_hnd(p, hnd, free_printer_entry, new_printer)) { - SAFE_FREE(new_printer); + + new_printer->notify.option=NULL; + + if ( !(new_printer->ctx = talloc_init("Printer Entry [0x%x]", (uint32)hnd)) ) { + DEBUG(0,("open_printer_hnd: talloc_init() failed!\n")); + close_printer_handle(p, hnd); return False; } - + if (!set_printer_hnd_printertype(new_printer, name)) { close_printer_handle(p, hnd); return False; -- cgit From 353b10b900d6cb3f200c1a14243866bc2c9c19aa Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 31 Mar 2003 20:37:31 +0000 Subject: Remove useless popt options (This used to be commit 861b2a464fed3a16f050972feed1900298fb0bcb) --- source3/utils/ntlm_auth.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3') diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index f02bd5f5b3..d924f92cce 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -457,8 +457,6 @@ enum { { "request-lm-key", 0, POPT_ARG_NONE, &request_lm_key, OPT_LM_KEY, "Retreive LM session key"}, { "request-nt-key", 0, POPT_ARG_NONE, &request_nt_key, OPT_NT_KEY, "Retreive NT session key"}, POPT_COMMON_SAMBA - POPT_COMMON_CONNECTION - POPT_COMMON_CREDENTIALS POPT_TABLEEND }; -- cgit